sketchucation logo sketchucation
    • Login
    πŸ›£οΈ Road Profile Builder | Generate roads, curbs and pavements easily Download

    Component axis problem

    Scheduled Pinned Locked Moved Developers' Forum
    18 Posts 5 Posters 1.2k Views 5 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • TIGT Offline
      TIG Moderator
      last edited by

      You already have an instance of the component definition when you make the conversion of group to component.
      The comp refers to its instance.
      The compdef refers to its definition.

      If you want to rotate/move that component's axes do this...

      If necessary...
      Get the transformation of the current instance [ tr]. Use compo.transform!(tr.inverse) to relocate it at the origin.

      Make the transformation needed to make the change[s] to the axes [ tr2].
      Apply that transformation thus: compo.transform!(tr2)
      Immediately apply that transformation to the definition thus:
      compdef.entities.transform_entities(tr2.inverse, compdef.entities.to_a)
      The instance should now appear as it was before, but the axes have changed...

      If approapriate...
      Use compo.transform!(tr) to move the group back where it was when you started...

      TIG

      1 Reply Last reply Reply Quote 0
      • PixeroP Offline
        Pixero
        last edited by

        Thanks for this both of you. I will try this as soon as I get a chance.

        1 Reply Last reply Reply Quote 0
        • PixeroP Offline
          Pixero
          last edited by

          Not sure why I'm having such a hard time getting this right but following TIGs guide, the Components BoundingBox/selection box remains unrotated until I open the component to edit. After exiting out of the edit component mode, the selection box is properly rotated, even though I still have some work left to get the component axis where I want it... πŸ˜• Coding can be sooo frustrating...

          1 Reply Last reply Reply Quote 0
          • X Offline
            XorUnison
            last edited by

            @pixero said:

            Not sure why I'm having such a hard time getting this right but following TIGs guide, the Components BoundingBox/selection box remains unrotated until I open the component to edit. After exiting out of the edit component mode, the selection box is properly rotated, even though I still have some work left to get the component axis where I want it... πŸ˜• Coding can be sooo frustrating...

            That's what I thought during my first month or so, but eventually it gets a lot easier as you learn how Sketchup and Ruby work.

            I don't know that phenomenon personally but I think it might be related to the component not being refreshed properly. You could try to redraw it:

               dcs = $dc_observers.get_latest_class
               dcs.redraw(entity,progress_bar_visible=false,is_recursive_call=false)
            
            1 Reply Last reply Reply Quote 0
            • TIGT Offline
              TIG Moderator
              last edited by

              Sorry, I rushed out the code snippets...
              You also need to do a compdef.invalidate_bounds
              after the changes, inside the model.start_operation...commit block, to make it change visually !
              http://www.sketchup.com/intl/en/developer/docs/ourdoc/componentdefinition#invalidate_bounds

              TIG

              1 Reply Last reply Reply Quote 0
              • PixeroP Offline
                Pixero
                last edited by

                Now I got the rotation of the boundingbox working as it should.
                However the transformation of the components axis is still at origo.
                Rotated correctly but not transformed.
                I must still be missing something? πŸ˜•

                
                tr = comp.transformation
                rotvector = pt1-pt0
                originvector = Geom;;Vector3d.new(1,0,0)
                angle = rotvector.angle_between originvector
                wfc.transform!(tr.inverse)	
                	
                tr2 = Geom;;Transformation.rotation(ORIGIN, Z_AXIS, angle) 
                comp.transform!(tr2)
                	
                compdef.entities.transform_entities(tr2.inverse, compdef.entities.to_a)
                compdef.invalidate_bounds
                comp.transform!(tr)	
                
                
                1 Reply Last reply Reply Quote 0
                • sdmitchS Offline
                  sdmitch
                  last edited by

                  @pixero said:

                  Now I got the rotation of the boundingbox working as it should.
                  However the transformation of the components axis is still at origo.
                  Rotated correctly but not transformed.
                  I must still be missing something? πŸ˜•

                  
                  > tr = comp.transformation
                  > rotvector = pt1-pt0
                  > originvector = Geom;;Vector3d.new(1,0,0)
                  > angle = rotvector.angle_between originvector
                  > wfc.transform!(tr.inverse)	
                  > 	
                  > tr2 = Geom;;Transformation.rotation(ORIGIN, Z_AXIS, angle) 
                  > comp.transform!(tr2)
                  > 	
                  > compdef.entities.transform_entities(tr2.inverse, compdef.entities.to_a)
                  > compdef.invalidate_bounds
                  > comp.transform!(tr)	
                  > 
                  

                  Did you ever get this figured out?

                  Here is what I came up with.

                  mod = Sketchup.active_model
                  ent = mod.active_entities
                  sel = mod.selection
                  grp = ent.first; #<--For test purposes
                  cmp = grp.to_component
                  cd = cmp.definition; cde = cd.entities; ct = cmp.transformation
                  cmp.transform! ct.inverse
                  org = cmp.bounds.corner(0)
                  #rotvector = pt1-pt0
                  #originvector = Geom;;Vector3d.new(1,0,0)
                  #angle = rotvector.angle_between originvector
                  #angle = -angle * (rotvector.y<=>0)
                  angle = -30.degrees #<--For test purposes
                  tr0 = Geom;;Transformation.rotation(org,Z_AXIS,angle)
                  cde.transform_entities(tr0,cde.to_a)
                  bb = Geom;;BoundingBox.new()
                  cde.each{|e| bb.add e.bounds}
                  org = bb.center
                  tr1 = Geom;;Transformation.new(org)
                  cde.transform_entities(tr1.inverse,cde.to_a)
                  cmp.transformation = cmp.transformation * tr1
                  cmp.transform! ct * tr0.inverse
                  cd.invalidate_bounds
                  
                  

                  Nothing is worthless, it can always be used as a bad example.

                  http://sdmitch.blogspot.com/

                  1 Reply Last reply Reply Quote 0
                  • PixeroP Offline
                    Pixero
                    last edited by

                    Yes I figured it out. Thanks anyway.

                    1 Reply Last reply Reply Quote 0
                    • PixeroP Offline
                      Pixero
                      last edited by

                      I have found a bug in my script that causes errors when drawn at certain angles.
                      When less than 90 degrees the angle needs to be negative and that works well with this fix but when it is 90 degrees or -90 degrees I cant seem to find a way of getting it correct without overwriting the values. Any clues how to do this?

                      def set_origin(compdef, compinst, pt0, pt1, pt3)
                      	tr1 = compinst.transformation
                      	rotvector = pt1-pt0
                      	originvector = Geom;;Vector3d.new(1,0,0)
                      	org = pt3
                      	angle = rotvector.angle_between originvector
                      	
                      	if angle < 90.degrees
                      		angle2 = -angle
                      	elsif angle > 90.degrees
                      		angle2 = angle	
                      	end #if
                      	
                              # This part don't trigger when it's not exactly 90 degrees. 
                              # If its just below or above but not enought to be caught in the <90 or >90. 
                              # 90.00000000000007 doesn't trigger it. (1.570796326794898 in radians)
                      
                      	if angle == 90.degrees  
                      		angle2 = -90.degrees
                      		puts "I'm 90"		
                      	elsif angle == -90.degrees 
                      		angle2 = 90.degrees
                      		puts "I'm -90"
                      	end
                      
                      	compinst.transform! tr1.inverse	
                      	tr2 = Geom;;Transformation.rotation(org, Z_AXIS, angle2) 
                      	tr3 = Geom;;Transformation.new(org)	
                      	compdef.entities.transform_entities(tr2, compdef.entities.to_a)		
                      	compdef.entities.transform_entities(tr3.inverse, compdef.entities.to_a)	
                      	compinst.transformation = compinst.transformation * tr3
                      	compinst.transform! tr1 * tr2.inverse
                      	compdef.invalidate_bounds
                      end #def
                      
                      1 Reply Last reply Reply Quote 0
                      • sdmitchS Offline
                        sdmitch
                        last edited by

                        Replace 90.degrees with Math::PI/2.

                        Nothing is worthless, it can always be used as a bad example.

                        http://sdmitch.blogspot.com/

                        1 Reply Last reply Reply Quote 0
                        • PixeroP Offline
                          Pixero
                          last edited by

                          Thanks, I tried that but the result is the same.
                          Is there a way of clamping very small values since 90.00000000000003 degrees seem to be enough not to work?

                          
                          	if angle == Math;;PI/2       
                          		angle2 = -90.degrees		
                          	elsif angle == -(Math;;PI/2) 
                          		angle2 = 90.degrees
                          	end
                          
                          1 Reply Last reply Reply Quote 0
                          • S Offline
                            slbaumgartner
                            last edited by

                            This issue is unavoidable with finite precision math on the computer. You have to choose a threshold of significance and then test for agreement within that tolerance, e.g.

                            if (angle.degrees - 90.0).abs < threshold

                            Of course, then you will become subject to all the same complaints as SketchUp gets for its internal 0.001 inch tolerance for consolidating Vertices - which is due to exactly the same situation!

                            1 Reply Last reply Reply Quote 0
                            • sdmitchS Offline
                              sdmitch
                              last edited by

                              I don't think the angle between vectors is ever going to be negative. Since you are measuring the angle from the x axis, you will need to use the y value of the rotvector to determine if the angle is negative or positive.

                              angle *= -(rotvector.y<=>0)

                              In a Sketchup rotation transformation, a positive angle is a counter clockwise rotation.

                              Nothing is worthless, it can always be used as a bad example.

                              http://sdmitch.blogspot.com/

                              1 Reply Last reply Reply Quote 0
                              • PixeroP Offline
                                Pixero
                                last edited by

                                I think I finally solved it by checking which of the pt0.y and pt1.y is larger and treat it different accordingly. Seems to work now.
                                Thanks for you input.

                                1 Reply Last reply Reply Quote 0
                                • PixeroP Offline
                                  Pixero
                                  last edited by

                                  I just thought I'd post this snippet in case it will help someone with a similar problem.

                                  def set_origin(compdef, compinst, pt0, pt1, pt3)
                                  	tr1 = compinst.transformation
                                  	rotvector = pt1-pt0 
                                  	originvector = Geom;;Vector3d.new(1,0,0)
                                  	org = pt3
                                  	angle = rotvector.angle_between originvector	
                                  	
                                  	if angle < 90.degrees 
                                  		angle2 = -angle
                                  	elsif angle > 90.degrees
                                  		angle2 = angle	
                                  	end #if
                                  
                                  	if angle == Math;;PI/2 
                                  		angle2 = -90.degrees 
                                  	end
                                  	
                                  	if pt0.y > pt1.y && angle == Math;;PI/2 #Check if it's drawn at 90 degrees but in opposite direction
                                  		angle2 = 90.degrees 
                                  	end
                                  	
                                  	compinst.transform! tr1.inverse	
                                  	tr2 = Geom;;Transformation.rotation(org, Z_AXIS, angle2) 
                                  	tr3 = Geom;;Transformation.new(org)	
                                  	compdef.entities.transform_entities(tr2, compdef.entities.to_a)		
                                  	compdef.entities.transform_entities(tr3.inverse, compdef.entities.to_a)	
                                  	compinst.transformation = compinst.transformation * tr3
                                  	compinst.transform! tr1 * tr2.inverse
                                  	compdef.invalidate_bounds
                                  
                                  end #def
                                  
                                  1 Reply Last reply Reply Quote 0
                                  • 1 / 1
                                  • First post
                                    Last post
                                  Buy SketchPlus
                                  Buy SUbD
                                  Buy WrapR
                                  Buy eBook
                                  Buy Modelur
                                  Buy Vertex Tools
                                  Buy SketchCuisine
                                  Buy FormFonts

                                  Advertisement