# eomAPI_ProjectPointOnSurf is very slow

Hello,

I'm seeking the points of a shape that is very close to a surface from which I want to build another form. For this reason I made this piece of code.

for (TopExp_Explorer ex1(aShape->Shape(),TopAbs_VERTEX) ; ex1.More(); ex1.Next())

{

TopoDS_Vertex V =TopoDS::Vertex(ex1.Current());

P = BRep_Tool::Pnt(V);

GeomAPI_ProjectPointOnSurf Proj (P, surface);

D = Proj.LowerDistance();

if(D

My problem is that the method GeomAPI_ProjectPointOnSurf is very slow. In Fact, it takes a long time for it to be calculated.

GeomAPI_ProjectPointOnSurf requires 62 milliseconds to be calculated for 100 Vertex.

there is another method to calculate the lower distance with the minimum time

Hi oumaia,

try to use ShapeAnalysis_Surface to project, or try another approach with Extrema_ExtPS.

I hope it helps

Regards

Thank you very much for your support. But I have used both methods and I havn't noticed any improvement. I think my implementation is not good.
compoundBuilder.Add( compoundShape,V);

here is the code that I used with ShapeAnalysis_Surface

ShapeAnalysis_Surface aSurf(surface);

aSurf.SetDomain(Umin,Umax,Vmin,Vmax);

for (TopExp_Explorer ex1(aShape->Shape(),TopAbs_VERTEX) ; ex1.More(); ex1.Next())

{

V =TopoDS::Vertex(ex1.Current());

P = BRep_Tool::Pnt(V);

Pn=aSurf.ValueOfUV(P,1);

aDist=aSurf.Value(Pn).Distance(P);

if(aDist

}

but the SetDomain doesn't work.

and the calcul is very slow

here is the code that I used with Extrema_ExtPS

BRepAdaptor_Surface Surf(F);
if(aDistance>ext.Value(k))
compoundBuilder.Add( compoundShape,V);

ext.Initialize(Surf,Umin,Umax,Vmin,Vmax,0,0);

for (TopExp_Explorer ex1(aShape->Shape(),TopAbs_VERTEX) ; ex1.More(); ex1.Next())

{

V =TopoDS::Vertex(ex1.Current());

P = BRep_Tool::Pnt(V);

ext.Perform(P);

extremum=ext.NbExt();

if(extremum!=0)

{

aDistance=ext.Value(1);

for(int k=2;k

aDistance=ext.Value(k);

if(aDistance

}

}

but also is very slow

Thank you very much for your help

What's your OCC version? Before 6.3.1, Extrema classes were slow, because SQRT operations.

Try to use SquareDistance() instead of Distance() method, and another thing you can add in your code is use tolU and tolV in Extrema_ExtPS. It will determine the conditions to stop iterations (check Extrema_ExtPS.hxx)

Regards,

Some very detailed advice. Thanks for sharing these insights.

Thank you Macedo.

I have used 6.3.0. But I downloaded opencascade 6.3.1 and I havn't found files Extrema_ExtPS improved.

I found the downloaded version 6.3.1 in this link

http://sourceforge.net/projects/opencascade/files/Open%20CASCADE%20fixes/6.3.1/

Thanks

Hello Macedo,

I downloaded version 6.3.1 but I found this bug when I built TKGeomAlgo

c: \ OpenCASCADE6.3.0 \ ros \ inc \ Intf_InterferencePolygonPolyhedron.gxx (1055): error C2039: 'SquareDistance': is not a member of 'Extrema_ExtElC'

Note that sourceforge hosts only patches over 6.3.1, not 6.3.1 itself. Many of those patches rely on source code changes and hence cannot be applied as is to 6.3.0.

As mentioned above, you might want to rely on ShapeAnalysis_Surface (in 6.3.0) to get maximum benefit of speed. Also consider use of its NextValueOfUV() method instead of ValueOfUV() if you iteratively project neighbor points.

const TColgp_Array1OfPnt& aPArr = thePoints->Array1();

Handle(ShapeAnalysis_Surface) aSAS = new ShapeAnalysis_Surface (aSurf);

int aS = aPArr.Lower(), aE = aPArr.Upper(), i;

for (i = aS; i gp_Pnt2d aPrev;

if (i == aS)

aPrev = aSAS->ValueOfUV (aPArr(i), theTol);

else

aPrev = aSAS->NextValueOfUV (aPrev, aPArr(i), theTol);

}

Hope this helps.

Roman

The time of projecting on the surface depends on the surface complexity. For quadrics (plane, cylinder, sphere), obviously, it is quick. For bsplines, it depends on the number of poles.

If you want not to be dependent on the surface type you may use the next approach. Triangulate your surface with an appropriate deflection, and project the points on triangulation. For fast rejection, you can use a tree of bounding boxes of triangles (see NCollection_UBTree class). This approach, of course, will require from you some forces to write the new functionality.

Thank you Michael,
{
{

But this method didn't work.

BRepMesh::Mesh(aShape->Shape(),1);

TopLoc_Location L;

Handle (Poly_Triangulation) facing = BRep_Tool::Triangulation(F,L);

Poly_Array1OfTriangle tri(1,facing->NbTriangles());

TColgp_Array1OfPnt tab(1,(facing->NbNodes()));

int m;

for (TopExp_Explorer ex1(aShape1->Shape(),TopAbs_VERTEX) ; ex1.More(); ex1.Next())

{

V =TopoDS::Vertex(ex1.Current());

P = BRep_Tool::Pnt(V);

m=1;

test=FALSE;

while((m

if(tab.Value(m).SquareDistance(P)

test=TRUE;

compoundBuilder.Add(compoundShape,V);

}

m++;

}

}

I tried to find the vertex closest to a cube, but this method did not work because I calculated the distance to the summit.

I have not figured out how to calculate the distance to the triangles.