How to using asiData_IVCurve2dNode::GetCONS() and asiData_IVCurve2dNode::SetCONS() ?

Guo issac

CAD practitioner
Dear Sergey Slyadnev,

I need to make a edge in Analysis Situs, by :

edge = BRepBuilderAPI_MakeEdge(Curve2d, Surf, Vert1, Vert2);

but I can't find how to define that Curve2d,
I can only find your similar codes like below for define a 3d curve. like below,
//----------------------------
Handle(asiData_IVCurveNode)
node_curve = Handle(asiData_IVCurveNode):: DownCast( cmdEngine::model->FindNodeByName(argv[2]) );

if ( node_curve.IsNull() )
{
interp->GetProgress().SendLogMessage(LogErr(Normal) << "Cannot find curve object with name %1." << argv[2]);
return TCL_ERROR;
}
double f, l;
Handle(Geom_Curve) C = node_curve->GetCurve(f,l);
//-------------------------------------
There is not a similar Get2dCurve() in asiData_IVCurve2dNode Class.

Is that need using asiData_IVCurve2dNode::GetCONS() or asiData_IVCurve2dNode::SetCONS()
to define a 2d curve for or not?
if it is, how to using it?
 

Andrey

Active CAD practitioner
Staff member

Dear Guo issac,​


Could you describe the context of the task, if possible?

In fact, Curve2d is a 2d curve in the parametric space of a surface. This curve, you define yourself. For example, Geom2d_BSplineCurve etc.

asiData_IVCurve2dNode - Data Node representing a single 2D curve in IV (Imperative Viewer). This node already has both a curve and a surface. I'm afraid that's not what you want (probably I could be wrong - I don't know the context of the task). Although, you can also make an edge from asiData_IVCurve2dNode (but keep in mind that asiData_IVCurve2dNode may not exist).
 

Guo issac

CAD practitioner
Screenshot_2022-05-17_13-13-32.png

I want make a edge like above picture, which is a screen shot of occt draw , axo viewer.
It made a projection edge from 4 elements: 2dcurve, cylinder surface, vertex1 and vertex2.
It using the draw command: mkedge edge 2dline cylinder_surf v1 v2

By compare the source codes of OCCT and Analysis Situs.
they are using different methods,

in OCCT mkedge command:
edge = BRepBuilderAPI_MakeEdge(C2d,S,V1,V2);


in Analysis Situs, make-edge command:
E = BRepBuilderAPI_MakeEdge(P1, P2);

so I need making a upgrade command do that.
am I right?

or could you show me some clue for finish this work?
 
Last edited:

Guo issac

CAD practitioner
I try to add a new command: mkedge-c2d proj_edge c2d cylinder_surf vert1 vert2
its codes as below,
the command crash when running: edge = BRepBuilderAPI_MakeEdge(C2d, S, V1, V2);

hopes you can give me some clue for solve this.

C++:
//=======================================================================
// mkedge-c2d, project a 2d curve on surface, guo
//=======================================================================
int mkedge_C2d(const Handle(asiTcl_Interp)& interp, int argc, const char** argv)
{

    if (argc < 3)
        return interp->ErrorOnWrongArgs(argv[0]);

    TopoDS_Edge edge;

    // Get 2d curve
    Handle(ActAPI_INode) node = cmdEngine::model->FindNodeByName(argv[2]);
    if ( node.IsNull() || !node->IsKind( STANDARD_TYPE(asiData_IVCurve2dNode) ) )
    {
      interp->GetProgress().SendLogMessage(LogErr(Normal) << "Node '%1' is not a 2d curve."<< argv[2]);
      return TCL_OK;
    }
    Handle(asiData_IVCurve2dNode) C2dNode = Handle(asiData_IVCurve2dNode)::DownCast(node);

    double f,l;
    Handle(Geom_Surface) SS;
    Handle(Geom2d_Curve) C2d = C2dNode->GetCONS(SS,f,l);

    if ( C2d.IsNull() )
    {
      interp->GetProgress().SendLogMessage(LogErr(Normal) << "Cannot find a 2d curve with the name %1." << argv[2]);
      return TCL_ERROR;
    }

     // Get geometry of a surface.
      Handle(asiData_IVSurfaceNode)
        nodeSurf = Handle(asiData_IVSurfaceNode)::DownCast( cmdEngine::model->FindNodeByName(argv[3]) );

      if ( nodeSurf.IsNull() )
      {
        interp->GetProgress().SendLogMessage(LogErr(Normal) << "Cannot find a Surface object with name %1." << argv[3]);
        return TCL_ERROR;
      }

      Handle(Geom_Surface) S = nodeSurf->GetSurface();

      // get V1 V2
      Handle(asiData_IVTopoItemNode)
        node1 = Handle(asiData_IVTopoItemNode)::DownCast( cmdEngine::model->FindNodeByName(argv[4]) );

      if ( node1.IsNull() )
      {
        interp->GetProgress().SendLogMessage(LogErr(Normal) << "Cannot find object with name %1." << argv[4]);
        return TCL_OK;
      }

      TopoDS_Shape aLocalShape1 = node1->GetShape();
      if ( aLocalShape1.ShapeType() != TopAbs_VERTEX )
      {
        interp->GetProgress().SendLogMessage(LogWarn(Normal) << "Object %1 is not a shell. Skipped." << argv[4]);
        return TCL_OK;
      }

      TopoDS_Vertex V1 = TopoDS::Vertex(aLocalShape1);

      Handle(asiData_IVTopoItemNode)
           node2 = Handle(asiData_IVTopoItemNode)::DownCast( cmdEngine::model->FindNodeByName(argv[5]) );

      if ( node2.IsNull() )
      {
          interp->GetProgress().SendLogMessage(LogErr(Normal) << "Cannot find object with name %1." << argv[5]);
          return TCL_OK;
      }

      TopoDS_Shape aLocalShape2 = node2->GetShape();
      if ( aLocalShape2.ShapeType() != TopAbs_VERTEX )
      {
          interp->GetProgress().SendLogMessage(LogWarn(Normal) << "Object %1 is not a shell. Skipped." << argv[5]);
          return TCL_OK;
      }

      TopoDS_Vertex V2 = TopoDS::Vertex(aLocalShape2);

      //----------------------
      if (argc == 6)
      {
          edge = BRepBuilderAPI_MakeEdge(C2d, S, V1, V2);
      }

    // Draw in IV.
    if ( !edge.IsNull() )
    {
      interp->GetPlotter().REDRAW_SHAPE(argv[1], edge, Color_Red, 1.0, true);
    }
    else
    {
      interp->GetProgress().SendLogMessage(LogErr(Normal) << "Cannot create edge: invalid arguments.");
      return TCL_ERROR;
    }

    return TCL_OK;

}
 

Andrey

Active CAD practitioner
Staff member
Dear Guo issac,

I looked at your code without thinking much about the correctness of taking nodes, etc. I have several questions:

1) Is the 2d curve in the surface parametrization area (for example, maybe the surface type is Geom_RectangularTrimmedSurface, etc.)?

2) Do V1, V2 lie on the surface S? Do V1, V2 lie on the 3d/2d curve you want to make?

Try constructing V1 and V2. Something like this:

gp_Pnt2d pf, pl;
pf = c2d->Value(f);
pl = c2d->Value(l);
GeomAdaptor_Surface surfAdapter(S);
gp_Pnt p1 = surfAdapter.Value(pf.X(), pf.Y());
gp_Pnt p2 = surfAdapter.Value(pl.X(), pl.Y());
TopoDS_Vertex v1 = BRepBuilderAPI_MakeVertex(p1);
TopoDS_Vertex v2 = BRepBuilderAPI_MakeVertex(p2);
....

In general, this is a surface substitution - the parametrization of the curve that we want to build may be different. But no one bothers us to try ....

4) As far as I understand, you need a projection - this can be done using other modules of OOCT, for example, GeomProjLib, etc. (of course, this could probably diverge from your idea....)

5) "Object %1 is not a shell. Skipped." -> "Object %1 is not a vertex. Skipped."

6) Some IsNull() checks are missing.

7) E = BRepBuilderAPI_MakeEdge(P1, P2); - builds a straight edge with end coordinates - P1 and P2.
edge = BRepBuilderAPI_MakeEdge(C2d,S,V1,V2); - additionally gives a "trajectory".
 

Guo issac

CAD practitioner
Thank you very much.
let me make more try on this.

And another quesiton is :
If I make a 2d curve, it can only displayed in the domain viewer.
It cannot show in the main viewer, and its parameters cannot displayed in parameter viewer also.

Is this normal?
 

Quaoar

Administrator
Staff member
It is as designed. The Part viewer is the 3D viewer for the modeling space, and the Domain viewer is the supplementary viewer for UV and 2D spaces. If you wanna show your 2D curve in the 3D viewer, you have to, mathematically speaking, embed it there. That is, evaluate it w.r.t. the surface. E.g., GeomAPI::To3d() does that for planes. For other surface types, approximation might be needed. You can check how BRepLib::BuildCurves3d works internally to accomplish such mapping.
 

Guo issac

CAD practitioner
Screenshot_2022-05-19_10-34-49.png

Finally, I fix the issue.
I found,
C++:
// Find Node by name.
    Handle(ActAPI_INode) node = cmdEngine::model->FindNodeByName(argv[3]);
    //
    if ( node.IsNull() || !node->IsKind( STANDARD_TYPE(asiData_IVCurve2dNode) ) )
    {
      interp->GetProgress().SendLogMessage(LogErr(Normal) << "Node '%1' is not a 2d curve."
                                                          << argv[3]);
      return TCL_OK;
    }
    //
    Handle(asiData_IVCurve2dNode) curve2dNode = Handle(asiData_IVCurve2dNode)::DownCast(node);

    // Get 2d curve.
    double f, l;
    Handle(Geom_Surface) aS;
    Handle(Geom2d_Curve) C2d = curve2dNode->GetCONS(aS,f,l);

above codes cannot get a trimmed 2d line correctly; But, if it is a infinite 2d line, it can working fine.
I don't know is it a bug of not.

So, I has to using other methods.

I using above codes to get a infinite 2d line, then trimming it.
then directly using:
edge = BRepBuilderAPI_MakeEdge(trimmedCurve, S, V1, V2);
Then the spiral edge made.

I combined the triming-curve command and mk-edge command into one single command.
do not get the trimmed curve by: Handle(Geom2d_Curve) C2d = curve2dNode->GetCONS(aS,f,l)
 
Last edited:
Top