CadQuery / cadquery

A python parametric CAD scripting framework based on OCCT
https://cadquery.readthedocs.io
Other
3.14k stars 289 forks source link

select faces by their age #1104

Open loirblitzt opened 2 years ago

loirblitzt commented 2 years ago

When modelling parametric pieces with a lot of steps, I find it hard to select the right faces with the existing Selectors. For instance, the order of the faces might change depending on the input parameters making the selector faces(">Z") hard to use.

So I was looking at ways to select faces by their age in the chain of parent workplanes.

  1. I first thought about patching functions like the extrude, revolve,loft, so that they add data to the workplane with information about the newly created faces. This information could be access to create new workplanes. However as seen in another issue, the workplane class seems rigid and not prone to changes.
  2. then i thought about comparing if faces from object.faces().objects are equal to faces in object.parent.faces().objects. However, when a face is modified by making a hole in it for example, the orgin face doesn't match with the modified face for obvious reason. I then noticed that the new not modified faces are added at the end of the object.faces().objects list, but I am not sure that I can trust the order of the faces in the list to determine their age.

Here is the sample code and piece that I used to experiment on this :

import cadquery as cq

out = cq.Workplane('XY').box(10,10,5,centered=(1,1,0))
out2 = out.faces('>Z').workplane().rect(3,3).extrude(4)

fout = out.faces().objects
fout2 = out2.faces().objects

#print the corresponding index of the face in the old version of the piece
print([ fout.index(a) if a in fout else None for a in fout2 ])
print([ a.Center() for a in fout2 ])
show_object(out2)
output : 
[0, 2, None, 3, 4, 1, None, None, None, None, None]
[Vector: (-5, 0 , 2.5),
 Vector: (0, -5 , 2.5),
 Vector: (0 , 0 , 5 ),
 Vector: (0 , 5.0, 2.5),
 Vector: (0 , 0 , 0),
 Vector: (5.0, 0 , 2.5),
 Vector: (0 , -1.5, 7.0),
 Vector: (1.5, 0 , 7.0),
 Vector: (0 , 1.5, 7.0),
 Vector: (-1.5, 0 , 7.0),
 Vector: ( 0 , 0 , 9.0)]

image

I have the following questions :

lorenzncode commented 2 years ago

Or is there a other way to mitigate selector fuzzyness ?

There is another way you might explore by using tagging. Here is an example:

result = cq.Workplane("XY").box(10, 10, 5, centered=(1, 1, 0)).tag("out1") result = result.faces(">Z").workplane().rect(3, 3).extrude(4).tag("out2")

face1 = result.faces(">Z", tag="out1") face2 = result.faces(">Z", tag="out2")

On Fri, Jun 10, 2022 at 8:28 PM Loibl-Vincent @.***> wrote:

When modelling parametric pieces with a lot of steps, I find it hard to select the right faces with the existing Selectors. For instance, the order of the faces might change depending on the input parameters making the selector faces(">Z") hard to use.

So I was looking at ways to select faces by their age in the chain of parent workplanes.

  1. I first thought about patching functions like the extrude, revolve, loft, so that they add data to the workplane with information about the newly created faces. This information could be access to create new workplanes. However as seen in another issue, the workplane class seems rigid and not prone to changes.
  2. then i thought about comparing if faces from object.faces().objects are equal to faces in object.parent.faces().objects. However, when a face is modified by making a hole in it for example, the orgin face doesn't match with the modified face for obvious reason. I then noticed that the new not modified faces are added at the end of the object.faces().objects list, but I am not sure that I can trust the order of the faces in the list to determine their age.

Here is the sample code and piece that I used to experiment on this :

import cadquery as cq

out = cq.Workplane('XY').box(10,10,5,centered=(1,1,0)) out2 = out.faces('>Z').workplane().rect(3,3).extrude(4)

fout = out.faces().objects fout2 = out2.faces().objects

print the corresponding index of the face in the old version of the piece

print([ fout.index(a) if a in fout else None for a in fout2 ]) print([ a.Center() for a in fout2 ]) show_object(out2)

output : [0, 2, None, 3, 4, 1, None, None, None, None, None] [Vector: (-5, 0 , 2.5), Vector: (0, -5 , 2.5), Vector: (0 , 0 , 5 ), Vector: (0 , 5.0, 2.5), Vector: (0 , 0 , 0), Vector: (5.0, 0 , 2.5), Vector: (0 , -1.5, 7.0), Vector: (1.5, 0 , 7.0), Vector: (0 , 1.5, 7.0), Vector: (-1.5, 0 , 7.0), Vector: ( 0 , 0 , 9.0)]

[image: image] https://user-images.githubusercontent.com/23189926/173165357-2bbc4ca6-4b59-4e56-a935-3157e6f969e0.png

I have the following questions :

  • Is selecting faces by their age, a valid workflow ? Or is there a other way to mitigate selector fuzzyness ?
  • Then should I go with my first or second option (or another) ?
  • Then is there a safe way to access the new (and not modified) faces ?

— Reply to this email directly, view it on GitHub https://github.com/CadQuery/cadquery/issues/1104, or unsubscribe https://github.com/notifications/unsubscribe-auth/AD5CQIA5UUH35QAWI7ZLP3LVOPMUJANCNFSM5YPGJMEQ . You are receiving this because you are subscribed to this thread.Message ID: @.***>