Finders
When using a visual interface to draw in 3D, selecting a face or an edge is trivial - the user just needs to click it.
In the case of code CAD, this is a more complicated operation - we need to find theses feature. This is what finders are for.
For this tutorial we will use this relatively complex shape (a simple house):
const main = ({ sketchCircle, sketchRectangle, Sketcher }) => {
let house = new Sketcher("XZ")
.hLine(50)
.vLine(60)
.line(-50, 20)
.closeWithMirror()
.extrude(30);
const window = sketchCircle(10, { plane: "XZ" })
.extrude(30)
.translate([10, 0, 50]);
const door = sketchRectangle(20, 30, { plane: "XZ" })
.extrude(30)
.translate([-20, -5, 15]);
house = house.cut(window).fuse(door);
return house;
};
We will use a feature of the viewer, where you can highlight programatically some faces (or edges).
Basic finders usage
Finding faces
In order to find faces, we create a face finder object. Let's say we want to find the face of the door
const main = ({ FaceFinder /*...*/ }) => {
let house = new Sketcher();
//...
const findDoor = new FaceFinder().inPlane("XZ", 35);
return {
shape: house,
highlight: findDoor,
};
};
This was fairly easy, the door is the face parallel to the plane XZ
, at
the coordiante 35
.
There are many different types of filters like inPlane
that allow you to
specify precisely which face you are interested in. For instance you can look
for faces that:
- have a certain type of surface
finder.ofSurfaceType("CYLINDRE")
will return the inside of the window. - contain a certain point
finder.containsPoint([0, -15, 80])
will return both sides of the roof
and other methods you can find in the API documentation
Finding edges
To find edges, it works in the same way, you just create and EdgeFinder
instead of a face finder and use the methods that are documented here.
For instance, to find the top of the roof
const main = ({ EdgeFinder /*...*/ }) => {
let house = new Sketcher();
//...
const findRooftop = new EdgeFinder().containsPoint([0, -15, 80]);
return {
shape: house,
highlight: findRooftop,
};
};
Combinating filters
By default you can chain different filter conditions. Only the shapes that follow all the conditions will be found. For instance, to find the window of the back of the house:
const main = ({ EdgeFinder /*...*/ }) => {
let house = new Sketcher();
//...
const backWindow = new EdgeFinder().ofCurveType("CIRCLE").inPlane("XZ");
return {
shape: house,
highlight: backWindow,
};
};
If you only use one of the filters you will see more edges highlighted.
Combinating with an either
conditions
In some cases you might want to combine elements with an OR condition, to find faces that fit either one condition or the other. For instance if we want to find both side faces:
const houseSides = new FaceFinder().either([
(f) => f.inPlane("YZ", 50),
(f) => f.inPlane("YZ", -50),
]);
Negating a condition
You might also want to specify the inverse of a condition, that is what not is
for. For instance, we can select the front window by just adding a not
to the
finder we created earlier
const frontWindow = new EdgeFinder()
.ofCurveType("CIRCLE")
.not((f) => f.inPlane("XZ"));
Note that it works because there are only two edges that are circles in the house.
Finding faces and edges
We have created finders so far and used them to hightlight faces and edges
- but what are they really useful for.
This will be mostly clear in the next chapter with modifications that can make a lot of use of finders.
But you can also need to find a specific face. For instance, we might want to have only the front face of the house
const main = ({ sketchCircle, sketchRectangle, Sketcher, FaceFinder }) => {
let house = new Sketcher("XZ")
.hLine(50)
.vLine(60)
.line(-50, 20)
.closeWithMirror()
.extrude(30);
const window = sketchCircle(10, { plane: "XZ" })
.extrude(30)
.translate([10, 0, 50]);
const door = sketchRectangle(20, 30, { plane: "XZ" })
.extrude(30)
.translate([-20, -5, 15]);
house = house.cut(window).fuse(door);
return new FaceFinder().inPlane("XZ", 30).find(house);
};