Why is projection keep giving results as if all shape are located at origin?

easternbun

CAD practitioner
I try to do projection of wire onto cube's shell using "BRepOffsetAPI_NormalProjection" API. The wire is above the cube in z direction.
The result is as if I projected the wire at z=0 or from within the cube (cube is built with center at origin). I get two segements of a wire no matter how far I move the wire out of the origin. Why is that?
1716192354767.png
1716192468392.png

okay with further testing, it just seems that I get random results with different shapes. Like Sphere just gives a point.

Code:
{
    BRepOffsetAPI_NormalProjection projector;

    // extract facet data to form our OCC shell
    MeshCore::MeshKernel meshFea = static_cast<Mesh::Feature*>(meshObj)->Mesh.getValue().getKernel();

    auto facearray = meshFea.GetFacets();

    BRep_Builder shellBuilder;
    TopoDS_Shell shell;
    shellBuilder.MakeShell(shell);
    for (int i = 0; i< facearray.size(); i++ )
    {
        auto geoface = meshFea.GetFacet(facearray[i]);
        //geoface.Transform(static_cast<Mesh::Feature*>(meshObj)->Placement.getValue().toMatrix());
        gp_Pnt v1(geoface._aclPoints[0].x,geoface._aclPoints[0].y,geoface._aclPoints[0].z);
        gp_Pnt v2(geoface._aclPoints[1].x,geoface._aclPoints[1].y,geoface._aclPoints[1].z);
        gp_Pnt v3(geoface._aclPoints[2].x,geoface._aclPoints[2].y,geoface._aclPoints[2].z);
        TopoDS_Wire wire = BRepBuilderAPI_MakePolygon(v1, v2, v3, Standard_True);
        TopoDS_Face face = BRepBuilderAPI_MakeFace(wire, Standard_True);
        shellBuilder.Add(shell, face);
    }
    if (!meshFea.HasOpenEdges())
        shell.Closed(true);

    projector.Init(shell);
   
    // move the wire to place above the cube
    auto pos = static_cast<Part::Feature*>(wireObj)->Placement.getValue().getPosition();
    gp_Trsf tempTransform;
    tempTransform.SetTranslation(gp_Vec(pos.x, pos.y, pos.z));
    TopLoc_Location loc(tempTransform);
    TopoDS_Shape shapeOfObj = Part::Feature::getShape(wireObj).Moved(loc);

    // add our moved wire to projector 
    projector.Add(shapeOfObj);
    projector.Compute3d(Standard_True);
    projector.SetParams(1.e-6, 1.e-6, GeomAbs_C1, 14, 16);
    projector.Build();

    // our projection result
    TopoDS_Shape wire = projector.Projection();
   
    auto featureObj = (Part::Feature*)Part::CreateDocumentObject("Part::Feature", pObjectName);
    auto prop = Part::GetPropertyOfDocumentObject<Part::PropertyPartShape>("Shape", featureObj);
    Part::SetValue<Part::PropertyPartShape>(prop, wire, false);

    // for GUI to display
    if (_recompute)
        featureObj->recomputeFeature();

    return featureObj;
}
 

Attachments

  • 1716191989797.png
    1716191989797.png
    20.9 KB · Views: 1
Last edited:

blobfish

CAD community veteran
shell construction:
I don't think you are building a valid shell. Have you checked the results for validity and content? Check Geometry in freecad will tell you. Several things you could do, but probably the simplest is to construct a list of faces and feed that list into BRepBuilderAPI_Sewing and let it build you a shell. You might not need a shell for BRepOffsetAPI_NormalProjection. In that case just build a compound of faces. Anytime you programmatically build a shape, you should run your results through BRepCheck_Analyzer and BRepTools_ShapeSet and make sure everything makes sense, at least during your algo development. These are just general comments and may or may not affect your current issue.

project onto cube:
What do you expect? edges on 1 face? edges on all 6 faces? I am not familiar with BRepOffsetAPI_NormalProjection, but it could be when a planar faces normal is orthogonal to the project direction, the projection is skipped. Modelling the cube with a slight draft would be a good test of this theory.

IMHO: converting a mesh into a BRep is a mistake.
 

easternbun

CAD practitioner
shell construction:
I don't think you are building a valid shell. Have you checked the results for validity and content? Check Geometry in freecad will tell you. Several things you could do, but probably the simplest is to construct a list of faces and feed that list into BRepBuilderAPI_Sewing and let it build you a shell. You might not need a shell for BRepOffsetAPI_NormalProjection. In that case just build a compound of faces. Anytime you programmatically build a shape, you should run your results through BRepCheck_Analyzer and BRepTools_ShapeSet and make sure everything makes sense, at least during your algo development. These are just general comments and may or may not affect your current issue.

project onto cube:
What do you expect? edges on 1 face? edges on all 6 faces? I am not familiar with BRepOffsetAPI_NormalProjection, but it could be when a planar faces normal is orthogonal to the project direction, the projection is skipped. Modelling the cube with a slight draft would be a good test of this theory.

IMHO: converting a mesh into a BRep is a mistake.
Thanks for the explanation and the good tips on shape evaluation.

I am expecting edges on 1 face(s), for the face(s) facing the wire.

The test seems that OCC projection kinda works on flat surface, but not ideally on curved. As you can see that flat surface seems to yield better (but not correct) results than curve surface.
The test is conducted by projecting two curves onto cylinderical mesh object. Each curve is oriented above the mesh object as shown in second image.
1716282764058.png
1716283066394.png
 
Last edited:
Top