• Login
sketchucation logo sketchucation
  • Login
โ„น๏ธ GoFundMe | Our friend Gus Robatto needs some help in a challenging time Learn More

Creating a bounding face around an instance

Scheduled Pinned Locked Moved Developers' Forum
10 Posts 4 Posters 544 Views
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.
  • Q Offline
    Qverburg
    last edited by 3 Feb 2010, 09:58

    Hello dear Ruby coders,

    Im making a script that places a window/door component which i have placed on a wall, into that wall.
    So it has to define all outer corners that are glued to the wall, then make a face onto that wall and push/pull this away so a hole is made into a wall.

    I have my script working, the only problem is that it only works when my wall is on a x or y axis. The reason for this is that i define my corner points of the window/door with the Boundingbox, and then check which of those points is on the face of my wall.
    My problem is that the bounding box of an object is always orthogonal so when i try to place a window in a wall thats not paralel to a x or y axis, there are no bbox corners touching my wall.

    Has anyone an idea to define the corners of my push/pull face in a different way?

    Here is the code where i define my corners of the push/pull face with the coordinates of the bbox corners.
    Its one of my first rubie scripts so the code is quite messy and inefficient I guess...
    Thanks for any help!

    #requesting all corners of the bbox
    		@@bbox = @@kozijn.bounds 
    		
    		#save all corners of the bbox in an array
    		@@pt		=	[]
    		@@pts		=	[]
    		@@pt[1] = @@bbox.corner 0
    		@@pt[2] = @@bbox.corner 1
    		@@pt[3] = @@bbox.corner 2
    		@@pt[4] = @@bbox.corner 3
    		@@pt[5] = @@bbox.corner 4
    		@@pt[6] = @@bbox.corner 5
    		@@pt[7] = @@bbox.corner 6
    		@@pt[8] = @@bbox.corner 7
    		
    		m	= 1
    		if @@nested == "true" #@@nested says if the instance is in a group or not
      		for q in @@group.entities
      			if q.typename == "Face"
      				#Check if corners of the bbox are on the face
          		for n in (1..8)
          			if q.classify_point(@@pt[n]) == 1 || q.classify_point(@@pt[n]) == 2 || q.classify_point(@@pt[n]) == 4
          				@@pts[m] 	= @@pt[n]
          				m 				=	m + 1
          				glued			=	q  #define which face the points are glued to
          			end #if
          		end #for
          	end	#if
      		end #for
      		@@kozijn.glued_to = glued
      		@@new_face 				= @@group.entities.add_face @@pts[1],@@pts[2], @@pts[4], @@pts[3]
      	else
      		#define all points glued to a face
      		for n in (1..8)
      			if @@kozijn.glued_to.classify_point(@@pt[n]) == 1 || @@kozijn.glued_to.classify_point(@@pt[n]) == 2 || @@kozijn.glued_to.classify_point(@@pt[n]) == 4
      				@@pts[m] 	= @@pt[n]
      				m 				=	m + 1
      			end
      		end	 
      		@@new_face = @@entities.add_face @@pts[1],@@pts[2], @@pts[4], @@pts[3]
    		end #if
    
    1 Reply Last reply Reply Quote 0
    • C Offline
      Chris Fullmer
      last edited by 3 Feb 2010, 10:25

      You could align your model axis to your windows before turning it into a component. Then the bounding box will align to the window snugly.

      Then to get the bounding box coordinates for you component, simply get the bounding box coordinates from the component's definition (the definition is placed on 0,0,0) and transform them by the components actual transformation. THe code might look something like this:

      my_comp = a_component t = my_comp.transformation comp_def = my_comp.definition def_t = comp_def.bounds.corner(0) new_t = t * def_t

      That final variable, new_t will be the real world location of the corner(0) of the component. Multiply any of the bounding box corner's you need by the transfomation like I showed to get their real world coordinates.

      Does that help at all? I'm not positive I answered the right question,

      Chris

      Lately you've been tan, suspicious for the winter.
      All my Plugins I've written

      1 Reply Last reply Reply Quote 0
      • Q Offline
        Qverburg
        last edited by 3 Feb 2010, 10:38

        Hi Chris,

        Thanks, I will try this. I'm not sure if the the bounding box will align to the new axes or will keep orientated to the old axes.
        Wouldnt there be another method to define the outer corners of the window that are touching the wall? I'm not positive that using the bounding box is the way to go.

        I'll give it a try anyway ๐Ÿ˜„

        thanks!

        1 Reply Last reply Reply Quote 0
        • C Offline
          Chris Fullmer
          last edited by 3 Feb 2010, 17:11

          The bounding box will align to the newly set axis.

          I agree that using the bounding box is not the most ideal way to to do it. It is how you said you wanted to to do it, so I was just suggesting how to make it work.

          What is your plugin trying to do, and what is the actual workflow that is expected for the user. That mgiht help come up with a workable solution.

          Chris

          Lately you've been tan, suspicious for the winter.
          All my Plugins I've written

          1 Reply Last reply Reply Quote 0
          • Q Offline
            Qverburg
            last edited by 8 Feb 2010, 16:06

            What my plugin should do is as follows:

            The user selects a window component(dynamic component with variable width and height).
            User places this component on a wall
            user selects my function (while window is selected)
            Functions does:
            -recognize which face the component is glued to
            -determine the corner points of te component
            -create a face which is as big as the component (the face is on the same place on the wall)
            -determine thickness of the wall
            -push pull the newly created face into the wall
            -place the component in the middle of the wall

            basicly i have everything working on orthogonal walls. Problem is determining the corner points of the component when its on a nonorthogonal wall.

            thanks for thinking with me ๐Ÿ˜„

            1 Reply Last reply Reply Quote 0
            • T Offline
              TIG Moderator
              last edited by 8 Feb 2010, 16:50

              Make an empty temp group.
              Add an instance of the component to it at the ORIGIN.
              Make a a new face at z=0 with normal [0,0,-1] that is somewhat bigger that the component's XY bounding box.
              Get the face's outer edges as an array.
              Intersect the face with the component.
              Erase the outer edges from the array.
              Now the remaining face.outer_loop.edges will equal the cutting shape of the component
              Get an array of the face.outer_loop.vertices and then convert those to their points.
              Now get the transformation of the inserted component and apply that to these points.
              You now have a list of points on the 'wall' outer face that correspond to the component's cutting hole.
              You can erase the original temp group***.
              Project these points using a raytest from their location along the vector face.normal.reverse
              The first thing they hit will be the back face of the 'wall' - the point is what you want - this is returned in raytest_result[0] - check it's a face with raytest_result[1][-1].
              You now have a list of points on the back face of the 'wall' projected from its front face.
              Use these points to make a new face on the inner surface.
              PushPull the face till it meets the front where the component is cutting its hole.
              ***When you make the temp component you can work out how deep it already cuts into any face it's glued on to by the amount of its bounding-box below Z=0 where it intersected with the temp face - use this as the maximum PushPull value so the inner reveals return just to the component's rear faces...
              ๐Ÿค“

              To make it really clever link the component-instance with the parts forming the inner hole with attributes - so it one is erased the other goes to, or it one is moved the other moves with it... โ“

              TIG

              1 Reply Last reply Reply Quote 0
              • Q Offline
                Qverburg
                last edited by 10 Feb 2010, 16:37

                @tig said:

                Make an empty temp group.
                Add an instance of the component to it at the ORIGIN.
                Make a a new face at z=0 with normal [0,0,-1] that is somewhat bigger that the component's XY bounding box.
                Get the face's outer edges as an array.
                Intersect the face with the component.
                Erase the outer edges from the array.
                Now the remaining face.outer_loop.edges will equal the cutting shape of the component
                Get an array of the face.outer_loop.vertices and then convert those to their points.
                Now get the transformation of the inserted component and apply that to these points.
                You now have a list of points on the 'wall' outer face that correspond to the component's cutting hole.
                You can erase the original temp group***.
                Project these points using a raytest from their location along the vector face.normal.reverse
                The first thing they hit will be the back face of the 'wall' - the point is what you want - this is returned in raytest_result[0] - check it's a face with raytest_result[1][-1].
                You now have a list of points on the back face of the 'wall' projected from its front face.
                Use these points to make a new face on the inner surface.
                PushPull the face till it meets the front where the component is cutting its hole.
                ***When you make the temp component you can work out how deep it already cuts into any face it's glued on to by the amount of its bounding-box below Z=0 where it intersected with the temp face - use this as the maximum PushPull value so the inner reveals return just to the component's rear faces...
                ๐Ÿค“

                To make it really clever link the component-instance with the parts forming the inner hole with attributes - so it one is erased the other goes to, or it one is moved the other moves with it... โ“

                Wow thanks alot!
                Im gonna work on this.

                Regards,
                Quintus

                1 Reply Last reply Reply Quote 0
                • J Offline
                  jessejames
                  last edited by 11 Feb 2010, 03:22

                  Tig's methods sounds correct but he missed the point that the "user" will be placing this window first and then running the script. There may be a simpler solution to this problem...

                  For me an ideal situation would be to tag the points that will rest on the "wall face". Then its just a matter of saying to the component HEY!, where are pt1, pt2, pt3, and pt4, located right now? this will make the job so much more easier.

                  So the much more simplified outline would be as follows

                  First what are the facts we can query at runtime of the script...?

                  1. the face upon which this componet will be cutting (CI.glued_to?)
                  2. the four corners within the component that will touch "this" face

                  With these two simple facts all one needs to do is create a loop on the face using the four points (or do an intersect of component and face and then search for the appropriate "hole loop") and voila! You know what to do next

                  Of course it's easy to outline a problem but i think my logic is sound, let me know if there are any holes here...?

                  Always sleep with a loaded gun under your pillow!

                  1 Reply Last reply Reply Quote 0
                  • Q Offline
                    Qverburg
                    last edited by 17 Feb 2010, 16:05

                    Thanks Im going to try both.

                    Now I can't seem to get the selecting device to work. I want to select the 2 oposite corners in the component but the best_picked doesnt support corners or intersections. Which function in the pickhelper should i use to get grip on a corner? ( Like the Line tool does)

                    thanks!

                    1 Reply Last reply Reply Quote 0
                    • C Offline
                      Chris Fullmer
                      last edited by 17 Feb 2010, 17:59

                      Use an inputpoint to get all the SketchUp inference points. This is a bare-bones code snippet that will make a tool, use an inputpoint and then draw that inputpoint to the screen.

                      ` class SUC_IP_POINT

                      def activate
                      	@ip1 = Sketchup::InputPoint.new
                      end
                      
                      def onMouseMove(flags, x, y, view)
                      	@ip1 = view.inputpoint x,y  
                      	view.invalidate
                      end
                      
                      def draw(view)
                      	@ip1.draw view
                      end
                      

                      end

                      Sketchup.active_model.select_tool(SUC_IP_POINT.new)`

                      So check that out, see if it helps.

                      Chris

                      Lately you've been tan, suspicious for the winter.
                      All my Plugins I've written

                      1 Reply Last reply Reply Quote 0
                      • 1 / 1
                      1 / 1
                      • First post
                        10/10
                        Last post
                      Buy SketchPlus
                      Buy SUbD
                      Buy WrapR
                      Buy eBook
                      Buy Modelur
                      Buy Vertex Tools
                      Buy SketchCuisine
                      Buy FormFonts

                      Advertisement