//function : ShapeProximityCalculator
//purpose : returns an object to compute the proximity value
//=======================================================================
-Handle(GEOM_Object) GEOMImpl_IMeasureOperations::ShapeProximityCalculator(
- Handle(GEOM_Object) theShape1,
- Handle(GEOM_Object) theShape2)
+Handle(GEOM_Object) GEOMImpl_IMeasureOperations::ShapeProximityCalculator
+ (Handle(GEOM_Object) theShape1,
+ Handle(GEOM_Object) theShape2)
{
SetErrorCode(KO);
if (theShape1.IsNull() || theShape2.IsNull())
return NULL;
+ Handle(GEOM_Function) aShapeFunc1 = theShape1->GetLastFunction();
+ Handle(GEOM_Function) aShapeFunc2 = theShape2->GetLastFunction();
+ if (aShapeFunc1.IsNull() || aShapeFunc2.IsNull())
+ return NULL;
+
Handle(GEOM_Object) aProximityCalc = GetEngine()->AddObject(GEOM_SHAPE_PROXIMITY);
if (aProximityCalc.IsNull())
return NULL;
aProximityFuncCoarse->GetDriverGUID() != GEOMImpl_ShapeProximityDriver::GetID())
return NULL;
- GEOMImpl_IProximity aProximity(aProximityFuncCoarse);
- Handle(GEOM_Function) aShapeFunc1 = theShape1->GetLastFunction();
- Handle(GEOM_Function) aShapeFunc2 = theShape2->GetLastFunction();
- if (aShapeFunc1.IsNull() || aShapeFunc2.IsNull())
- return NULL;
-
+ GEOMImpl_IProximity aProximity (aProximityFuncCoarse);
aProximity.SetShapes(aShapeFunc1, aShapeFunc2);
- // Perform
- try
- {
- OCC_CATCH_SIGNALS;
- if (!GetSolver()->ComputeFunction(aProximityFuncCoarse))
- {
- SetErrorCode("shape proximity driver failed");
- return NULL;
- }
- }
- catch (Standard_Failure& aFail)
- {
- SetErrorCode(aFail.GetMessageString());
- return NULL;
- }
-
//Make a Python command
- GEOM::TPythonDump(aProximityFuncCoarse) << "p = geompy.ShapeProximity()";
- GEOM::TPythonDump(aProximityFuncCoarse) << "p.setShapes(" << theShape1 << ", " << theShape2 << ")";
+ GEOM::TPythonDump pd (aProximityFuncCoarse);
+ pd << "p = geompy.ShapeProximity()\n";
+ pd << "p.setShapes(" << theShape1 << ", " << theShape2 << ")";
SetErrorCode(OK);
return aProximityCalc;
//function : SetShapeSampling
//purpose : set number sample points to compute the coarse proximity
//=======================================================================
-void GEOMImpl_IMeasureOperations::SetShapeSampling(
- Handle(GEOM_Object) theCalculator,
- Handle(GEOM_Object) theShape,
- const Standard_Integer theNbSamples)
+void GEOMImpl_IMeasureOperations::SetShapeSampling(Handle(GEOM_Object) theCalculator,
+ Handle(GEOM_Object) theShape,
+ const Standard_Integer theNbSamples)
{
SetErrorCode(KO);
if (theShape.IsNull() ||
theNbSamples <= 0)
return ;
-
Handle(GEOM_Function) aProximityFuncCoarse = theCalculator->GetFunction(1);
if (aProximityFuncCoarse.IsNull() ||
aProximityFuncCoarse->GetDriverGUID() != GEOMImpl_ShapeProximityDriver::GetID())
GEOMImpl_IProximity aProximity(aProximityFuncCoarse);
Handle(GEOM_Function) aShape1, aShape2;
aProximity.GetShapes(aShape1, aShape2);
- if (aShape1 == aShapeFunc)
+ if (aShape1->GetValue() == aShapeFunc->GetValue())
aProximity.SetNbSamples(PROXIMITY_ARG_SAMPLES1, theNbSamples);
- else if (aShape2 == aShapeFunc)
+ else if (aShape2->GetValue() == aShapeFunc->GetValue())
aProximity.SetNbSamples(PROXIMITY_ARG_SAMPLES2, theNbSamples);
//Make a Python command
- GEOM::TPythonDump(aProximityFuncCoarse) << "p.setSampling(" << theShape << ", " << theNbSamples << ")";
+ GEOM::TPythonDump(aProximityFuncCoarse, /*append=*/true) <<
+ "p.setSampling(" << theShape << ", " << theNbSamples << ")";
SetErrorCode(OK);
}
//function : GetCoarseProximity
//purpose : compute coarse proximity
//=======================================================================
-Standard_Real GEOMImpl_IMeasureOperations::GetCoarseProximity(Handle(GEOM_Object) theCalculator)
+Standard_Real GEOMImpl_IMeasureOperations::GetCoarseProximity(Handle(GEOM_Object) theCalculator,
+ bool doPythonDump)
{
SetErrorCode(KO);
if (theCalculator.IsNull())
- return NULL;
+ return -1;
- Handle(GEOM_Function) aProximityFuncCoarse;
- for (int i = 1; i <= theCalculator->GetNbFunctions() && aProximityFuncCoarse.IsNull(); ++i)
- {
- Handle(GEOM_Function) aFunc = theCalculator->GetFunction(i);
- if (!aFunc.IsNull() && aFunc->GetType() == PROXIMITY_COARSE)
- aProximityFuncCoarse = aFunc;
- }
- //Check if the function is set correctly
+ Handle(GEOM_Function) aProximityFuncCoarse = theCalculator->GetFunction(1);
if (aProximityFuncCoarse.IsNull() ||
- aProximityFuncCoarse->GetDriverGUID() != GEOMImpl_ShapeProximityDriver::GetID())
- return NULL;
+ aProximityFuncCoarse->GetDriverGUID() != GEOMImpl_ShapeProximityDriver::GetID() ||
+ aProximityFuncCoarse->GetType() != PROXIMITY_COARSE)
+ return -1;
- GEOMImpl_IProximity aProximity(aProximityFuncCoarse);
+ // Perform
+ // We have to recompute the function each time,
+ // because the number of samples can be changed
+ try {
+ OCC_CATCH_SIGNALS;
+ if (!GetSolver()->ComputeFunction(aProximityFuncCoarse)) {
+ SetErrorCode("shape proximity driver failed");
+ return -1;
+ }
+ }
+ catch (Standard_Failure& aFail) {
+ SetErrorCode(aFail.GetMessageString());
+ return -1;
+ }
//Make a Python command
- GEOM::TPythonDump(aProximityFuncCoarse) << "value = p.coarseProximity()";
+ if (doPythonDump)
+ GEOM::TPythonDump(aProximityFuncCoarse, /*append=*/true) << "value = p.coarseProximity()";
SetErrorCode(OK);
+ GEOMImpl_IProximity aProximity (aProximityFuncCoarse);
return aProximity.GetValue();
}
{
SetErrorCode(KO);
if (theCalculator.IsNull())
- return NULL;
+ return -1;
- Handle(GEOM_Function) aProximityFuncFine = theCalculator->GetLastFunction();
- if (aProximityFuncFine.IsNull())
- {
- // perform coarse computatiuon beforehand
- GetCoarseProximity(theCalculator);
- aProximityFuncFine = theCalculator->GetLastFunction();
- }
- if (aProximityFuncFine->GetType() != PROXIMITY_PRECISE)
- aProximityFuncFine = theCalculator->AddFunction(GEOMImpl_ShapeProximityDriver::GetID(), PROXIMITY_PRECISE);
Handle(GEOM_Function) aProximityFuncCoarse = theCalculator->GetFunction(1);
+ Handle(GEOM_Function) aProximityFuncFine = theCalculator->GetFunction(2);
+ if (aProximityFuncFine.IsNull())
+ aProximityFuncFine = theCalculator->AddFunction
+ (GEOMImpl_ShapeProximityDriver::GetID(), PROXIMITY_PRECISE);
+
//Check if the functions are set correctly
if (aProximityFuncCoarse.IsNull() ||
aProximityFuncCoarse->GetDriverGUID() != GEOMImpl_ShapeProximityDriver::GetID() ||
aProximityFuncFine.IsNull() ||
aProximityFuncFine->GetDriverGUID() != GEOMImpl_ShapeProximityDriver::GetID())
- return NULL;
+ return -1;
+
+ // perform coarse computation beforehand
+ GetCoarseProximity(theCalculator, /*doPythonDump=*/false);
// transfer parameters from the coarse to precise calculator
- GEOMImpl_IProximity aCoarseProximity(aProximityFuncCoarse);
+ GEOMImpl_IProximity aCoarseProximity (aProximityFuncCoarse);
Handle(GEOM_Function) aShape1, aShape2;
aCoarseProximity.GetShapes(aShape1, aShape2);
if (aShape1.IsNull() || aShape2.IsNull())
- return NULL;
+ return -1;
gp_Pnt aProxPnt1, aProxPnt2;
- BRepExtrema_ProximityDistTool::ProxPnt_Status aStatus1, aStatus2;
Standard_Integer intStatus1, intStatus2;
aCoarseProximity.GetProximityPoints(aProxPnt1, aProxPnt2);
aCoarseProximity.GetStatusOfPoints(intStatus1, intStatus2);
- aStatus1 = (BRepExtrema_ProximityDistTool::ProxPnt_Status)intStatus1;
- aStatus2 = (BRepExtrema_ProximityDistTool::ProxPnt_Status)intStatus2;
-
Standard_Real aResultValue = aCoarseProximity.GetValue();
- // call precise calculator only if at least one point is in the middle of the shape
- if (aStatus1 == BRepExtrema_ProximityDistTool::ProxPnt_Status_MIDDLE ||
- aStatus2 == BRepExtrema_ProximityDistTool::ProxPnt_Status_MIDDLE)
- {
- GEOMImpl_IProximity aFineProximity(aProximityFuncFine);
- aFineProximity.SetShapes(aShape1, aShape2);
- aFineProximity.SetProximityPoints(aProxPnt1, aProxPnt2);
- aFineProximity.SetStatusOfPoints(intStatus1, intStatus2);
-
- // Perform
- try
- {
- OCC_CATCH_SIGNALS;
- if (!GetSolver()->ComputeFunction(aProximityFuncFine))
- {
- SetErrorCode("shape proximity driver failed");
- return NULL;
- }
- }
- catch (Standard_Failure& aFail)
- {
- SetErrorCode(aFail.GetMessageString());
- return NULL;
- }
+ GEOMImpl_IProximity aFineProximity (aProximityFuncFine);
+ aFineProximity.SetShapes(aShape1, aShape2);
+ aFineProximity.SetProximityPoints(aProxPnt1, aProxPnt2);
+ aFineProximity.SetStatusOfPoints(intStatus1, intStatus2);
+ aFineProximity.SetValue(aResultValue); // in some cases this value cannot be precised
- aResultValue = aFineProximity.GetValue();
+ // Perform
+ try {
+ OCC_CATCH_SIGNALS;
+ if (!GetSolver()->ComputeFunction(aProximityFuncFine)) {
+ SetErrorCode("shape proximity driver failed");
+ return -1;
+ }
}
+ catch (Standard_Failure& aFail) {
+ SetErrorCode(aFail.GetMessageString());
+ return -1;
+ }
+
+ aResultValue = aFineProximity.GetValue();
+ aFineProximity.GetProximityPoints(aProxPnt1, aProxPnt2);
//Make a Python command
- GEOM::TPythonDump(aProximityFuncCoarse) << "value = p.preciseProximity()";
+ GEOM::TPythonDump(aProximityFuncCoarse, /*append=*/true) << "value = p.preciseProximity()";
SetErrorCode(OK);
return aResultValue;
// Methods to compute proximity between two shapes
Standard_EXPORT Handle(GEOM_Object) ShapeProximityCalculator(Handle(GEOM_Object) theShape1,
Handle(GEOM_Object) theShape2);
- Standard_EXPORT Standard_Real GetCoarseProximity(Handle(GEOM_Object) theCalculator);
+ Standard_EXPORT Standard_Real GetCoarseProximity(Handle(GEOM_Object) theCalculator,
+ bool doPythonDump = true);
Standard_EXPORT Standard_Real GetPreciseProximity(Handle(GEOM_Object) theCalculator);
Standard_EXPORT void SetShapeSampling(Handle(GEOM_Object) theCalculator,
Handle(GEOM_Object) theShape,
return 0;
Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
- GEOMImpl_IProximity aProximity(aFunction);
+ GEOMImpl_IProximity aProximity (aFunction);
Handle(GEOM_Function) aShapeFunc1, aShapeFunc2;
aProximity.GetShapes(aShapeFunc1, aShapeFunc2);
tessellateShape(aShape1);
tessellateShape(aShape2);
- // compute proximity basing of the tessellation
+ // compute proximity basing on the tessellation
BRepExtrema_ShapeProximity aCalcProx;
aCalcProx.LoadShape1(aShape1);
aCalcProx.LoadShape2(aShape2);
}
else if (aFunction->GetType() == PROXIMITY_PRECISE)
{
+ // coarse proximity value
+ // in some cases this value cannot be precised
+ // it can be precised only if at least one point is in the middle of the shape
+ aValue = aProximity.GetValue();
+
TopAbs_ShapeEnum aType1 = aShape1.ShapeType();
TopAbs_ShapeEnum aType2 = aShape2.ShapeType();
## Computes proximity between two shapes of the same type
def proximity(self, shape1, shape2):
self.setShapes(shape1, shape2)
- self.coarseProximity()
+ #self.coarseProximity()
return self.preciseProximity()
pass
OY = geompy.MakeVectorDXDYDZ(0, 1, 0)
OZ = geompy.MakeVectorDXDYDZ(0, 0, 1)
-# create arc and segment
+# Case 1: two bezier curves (original Cas2_29468.py)
+from math import sqrt
+
+# 283x384
+szY = 384
+listOfPtsRed_gimp = [(10,84), (54,96),(145,146),(167,167),(185,212),(187,234),(176,302)]
+listOfPtsBlue_gimp = [(120,72),(170,87),(227,118),(238,126),(243,157),(203,216),(134,281),(94,324)]
+#
+listOfPtsRed = [(x,szY-y) for x,y in listOfPtsRed_gimp]
+listOfPtsBlue = [(x,szY-y) for x,y in listOfPtsBlue_gimp]
+#
+verticesRed = [geompy.MakeVertex(x,y,0) for x,y in listOfPtsRed]
+verticesBlue = [geompy.MakeVertex(x,y,0) for x,y in listOfPtsBlue]
+for i,(x,y) in enumerate(listOfPtsRed):
+ geompy.addToStudy(geompy.MakeVertex(x,y,0),"red_pt{}".format(i))
+for i,(x,y) in enumerate(listOfPtsBlue):
+ geompy.addToStudy(geompy.MakeVertex(x,y,0),"blue_pt{}".format(i))
+redEdge = geompy.MakeBezier(verticesRed)
+blueEdge = geompy.MakeBezier(verticesBlue)
+#
+geompy.addToStudy(redEdge,"red")
+geompy.addToStudy(blueEdge,"blue")
+
+XY_red = (152,214)
+XY_blue = (215,260)
+exp_red = geompy.MakeVertex(*XY_red,0)
+exp_blue = geompy.MakeVertex(*XY_blue,0)
+geompy.addToStudy(exp_red,"exp_red")
+geompy.addToStudy(exp_blue,"exp_blue")
+
+p = geompy.ShapeProximity()
+p.setShapes(redEdge, blueEdge)
+p.setSampling(redEdge, 1000)
+p.setSampling(blueEdge, 1000)
+p_coarse = p.coarseProximity()
+p_precise = p.preciseProximity()
+print( "coarse = {} ; fine = {}".format(p_coarse,p_precise) )
+print( "Manually obtained value = {}".format( sqrt( (XY_red[0]-XY_blue[0])**2 + (XY_red[1]-XY_blue[1])**2 ) ) )
+
+assert(math.fabs(p_coarse - 84.89994110) < 1.e-7)
+
+# Case 2: two bezier curves (different coarse and fine proximities)
+V1 = geompy.MakeVertex(10, 10, 0)
+V2 = geompy.MakeVertex(20, -10, 0)
+V3 = geompy.MakeVertex(30, 0, 0)
+V4 = geompy.MakeVertex(0, -3, 0)
+V5 = geompy.MakeVertex(13, -10, 0)
+V6 = geompy.MakeVertex(25, 10, 0)
+V7 = geompy.MakeVertex(30, 5, 0)
+BC1 = geompy.MakeBezier([ O, V1, V2, V3], False, "BC1")
+BC2 = geompy.MakeBezier([V4, V5, V6, V7], False, "BC2")
+
+pcalc = geompy.ShapeProximity()
+pcalc.setShapes(BC1, BC2)
+p_coarse = pcalc.coarseProximity()
+p_fine = pcalc.preciseProximity()
+
+assert(math.fabs(p_coarse - 7.3126564) < 1.e-7)
+assert(math.fabs(p_fine - 7.380468495) < 1.e-7)
+
+# Case 3: arc and segment
Vertex_1 = geompy.MakeVertex(0, 0, -1)
Vertex_2 = geompy.MakeVertex(1, 0, 0)
Vertex_3 = geompy.MakeVertex(0, 0, 1)
OY = geompy.MakeVectorDXDYDZ(0, 1, 0)
OZ = geompy.MakeVectorDXDYDZ(0, 0, 1)
-# create conical and planar faces
+# Case 1: cylinder and sphere (different coarse and fine proximities)
+OCyl = geompy.MakeVertex(0, -5, 15)
+Cyl = geompy.MakeCylinder(OCyl, OY, 3, 10, "Cyl")
+AX1 = geompy.MakeTranslation(OX, 0, 0, 15, "AX1")
+geompy.Rotate(Cyl, AX1, -20.0*math.pi/180.0)
+Cyl_face = geompy.SubShapeAllSortedCentres(Cyl, geompy.ShapeType["FACE"], "Face")[1]
+Sph = geompy.MakeSphereR(10, "Sph")
+Box_1 = geompy.MakeBoxDXDYDZ(40, 40, 27.071067)
+Translation_1 = geompy.MakeTranslation(Box_1, -20, -20, -20)
+Cut_1 = geompy.MakeCutList(Sph, [Translation_1], True, "Cut_1")
+Sph_face = geompy.SubShapeAllSortedCentres(Cut_1, geompy.ShapeType["FACE"], "Face")[1]
+
+pcalc = geompy.ShapeProximity()
+pcalc.setShapes(Cyl_face, Sph_face)
+p_coarse = pcalc.coarseProximity()
+p_fine = pcalc.preciseProximity()
+
+assert(math.fabs(p_coarse - 9.8649933) < 1.e-7)
+assert(math.fabs(p_fine - 7.6984631) < 1.e-7)
+
+geompy.MakeVertex(0, 2.63303, 17.2342, "p1")
+geompy.MakeVertex(0, 0, 10, "p2")
+
+print("With sampling 0: coarse = {} ; fine = {}".format(p_coarse, p_fine))
+
+pcalc.setSampling(Cyl_face, 100) # number of sample points for the first shape
+pcalc.setSampling(Sph_face, 100) # number of sample points for the second shape
+p_coarse = pcalc.coarseProximity()
+p_fine = pcalc.preciseProximity()
+
+print("With sampling 100: coarse = {} ; fine = {}".format(p_coarse, p_fine))
+
+pcalc.setSampling(Cyl_face, 1000) # number of sample points for the first shape
+pcalc.setSampling(Sph_face, 1000) # number of sample points for the second shape
+p_coarse = pcalc.coarseProximity()
+p_fine = pcalc.preciseProximity()
+
+print("With sampling 1000: coarse = {} ; fine = {}".format(p_coarse, p_fine))
+
+# Case 2: conical and planar faces
Cone_1 = geompy.MakeConeR1R2H(100, 0, 300)
Cone_1_face_3 = geompy.GetSubShape(Cone_1, [3])
Cone_1_wire_4 = geompy.GetSubShape(Cone_1, [4])
-Face_1 = geompy.MakeFaceFromSurface(Cone_1_face_3, Cone_1_wire_4)
+Face_1 = geompy.MakeFaceFromSurface(Cone_1_face_3, Cone_1_wire_4, "Face_1")
Face_1_edge_5 = geompy.GetSubShape(Face_1, [5])
Face_2 = geompy.MakeFaceObjHW(Face_1_edge_5, 200, 200)
geompy.Rotate(Face_2, OY, 90*math.pi/180.0)
Face_2_vertex_7 = geompy.GetSubShape(Face_2, [7])
-Translation_1 = geompy.MakeTranslationTwoPoints(Face_2, Face_2_vertex_7, O)
+Translation_1 = geompy.MakeTranslationTwoPoints(Face_2, Face_2_vertex_7, O, "Translation_1")
shape1 = Face_1
shape2 = Translation_1
assert(math.fabs(proximity1 - proximity2_fine) < 1.e-7)
assert(math.fabs(proximity2_coarse - 127.1141386) < 1.e-7)
-assert(math.fabs(proximity2_fine - 94.8683298) < 1.e-7)
+#assert(math.fabs(proximity2_fine - 94.8683298) < 1.e-7)
+assert(math.fabs(proximity2_fine - 127.1141386) < 1.e-7)
+
+geompy.MakeVertex(0, 0, 300, "p3")
+geompy.MakeVertex(-63.2456, 0, 189.737, "p4")