bos #29468: Advanced geometry features: distance Edge-Edge & Face-Face

This commit is contained in:
azv 2022-06-17 17:19:17 +03:00 committed by jfa
parent 66be812a4e
commit 0ca387bcab
23 changed files with 1076 additions and 0 deletions

View File

@ -0,0 +1,39 @@
# Shape Proximity
import salome
salome.salome_init_without_session()
import GEOM
from salome.geom import geomBuilder
geompy = geomBuilder.New()
# create conical and planar faces
O = geompy.MakeVertex(0, 0, 0)
OX = geompy.MakeVectorDXDYDZ(1, 0, 0)
OY = geompy.MakeVectorDXDYDZ(0, 1, 0)
OZ = geompy.MakeVectorDXDYDZ(0, 0, 1)
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_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)
shape1 = Face_1
shape2 = Translation_1
# perform proximity calculation with the default parameters
p1 = geompy.ShapeProximity()
proximity1 = p1.proximity(shape1, shape2)
print("Proximity with default parameters: ", proximity1)
# perform proximity calculation with custom parameters
p2 = geompy.ShapeProximity()
p2.setShapes(shape1, shape2)
p2.setSampling(shape1, 100) # number of sample points for the first shape
p2.setSampling(shape2, 40) # number of sample points for the second shape
proximity2_coarse = p2.coarseProximity()
proximity2_fine = p2.preciseProximity()
print("Proximity with custom parameters: coarse = ", proximity2_coarse, "; precise = ", proximity2_fine)

View File

@ -135,4 +135,5 @@ SET(GOOD_TESTS
working_with_groups_ex06.py working_with_groups_ex06.py
GEOM_Field.py GEOM_Field.py
check_self_intersections_fast.py # OCC > 6.9.0 check_self_intersections_fast.py # OCC > 6.9.0
shape_proximity.py
) )

View File

@ -0,0 +1,31 @@
/*!
\page shape_proximity_page Shape Proximity
The Shape Proximity operation calculates maximal of all possible distances between two shapes.
This is just a TUI functionality. The provided class
<pre>
geompy.ShapeProximity()
</pre>
has an interface to compute proximity value with default parameters
<pre>
p = geompy.ShapeProximity()
value = p.proximity(shape1, shape2)
</pre>
Moreover, it also provides the functionality to customize the calculation.
For example, compute coarse proximity value basing on the number of sampling points for each shape,
or compute the precise value as a refining operation after the coarse value calculation.
<pre>
p = geompy.ShapeProximity()
p.setShapes(shape1, shape2) # customize calculator with input shapes
p.setSampling(shape1, 100) # assign number of sample points for the first shape
p.setSampling(shape2, 25) # assign number of sample points for the second shape
coarse_proximity = p.coarseProximity() # rough proximity value basing on the shape sampling and tessellation
fine_proximity = p.preciseProximity() # more precise proximity value using exact shapes
</pre>
See also a \ref tui_shape_proximity_page "TUI example".
*/

View File

@ -22,6 +22,7 @@
<li>\subpage tui_check_self_intersections_fast_page</li> <li>\subpage tui_check_self_intersections_fast_page</li>
<li>\subpage tui_fast_intersection_page</li> <li>\subpage tui_fast_intersection_page</li>
<li>\subpage tui_check_conformity_page</li> <li>\subpage tui_check_conformity_page</li>
<li>\subpage tui_shape_proximity_page</li>
</ul> </ul>
*/ */

View File

@ -0,0 +1,6 @@
/*!
\page tui_shape_proximity_page Compute Proximity between Shapes
\tui_script{shape_proximity.py}
*/

View File

@ -21,6 +21,7 @@
<li>\subpage whatis_page "WhatIs"</li> <li>\subpage whatis_page "WhatIs"</li>
<li>\subpage inspect_object_operation_page "Inspect Object"</li> <li>\subpage inspect_object_operation_page "Inspect Object"</li>
<li>\subpage shape_statistics_operation_page "Shape Statistics"</li> <li>\subpage shape_statistics_operation_page "Shape Statistics"</li>
<li>\subpage shape_proximity_page "Shapes Proximity"</li>
</ul> </ul>
\n To check their integrity: \n To check their integrity:

View File

@ -4833,6 +4833,38 @@ module GEOM
* \param theShape Shape for update. * \param theShape Shape for update.
*/ */
double UpdateTolerance(in GEOM_Object theShape); double UpdateTolerance(in GEOM_Object theShape);
/*!
* \brief Get the calculator for the proximity value between the given shapes.
* \param theShape1,theShape2 Shapes to find proximity.
* \return The calculator object.
*/
GEOM_Object ShapeProximityCalculator(in GEOM_Object theShape1, in GEOM_Object theShape2);
/*!
* \brief Set number sample points to compute the coarse proximity.
* \param theCalculator Proximity calculator.
* \param theShape Shape to be samples.
* \param theNbSamples Number of samples points.
*/
void SetShapeSampling(in GEOM_Object theCalculator,
in GEOM_Object theShape,
in long theNbSamples);
/*!
* \brief Compute coarse value of the proximity basing on the polygonal representation of shapes.
* \param theCalculator Proximity calculator.
* \return Proximity value.
*/
double GetCoarseProximity(in GEOM_Object theCalculator);
/*!
* \brief Compute precise value of the proximity basing on the exact shapes.
* \param theCalculator Proximity calculator.
* \return Proximity value.
*/
double GetPreciseProximity(in GEOM_Object theCalculator);
}; };
// # GEOM_IGroupOperations: // # GEOM_IGroupOperations:

View File

@ -95,6 +95,7 @@ SET(GEOMImpl_HEADERS
GEOMImpl_ILine.hxx GEOMImpl_ILine.hxx
GEOMImpl_IPatchFace.hxx GEOMImpl_IPatchFace.hxx
GEOMImpl_IPlane.hxx GEOMImpl_IPlane.hxx
GEOMImpl_IProximity.hxx
GEOMImpl_IMarker.hxx GEOMImpl_IMarker.hxx
GEOMImpl_ITranslate.hxx GEOMImpl_ITranslate.hxx
GEOMImpl_IMirror.hxx GEOMImpl_IMirror.hxx
@ -182,6 +183,7 @@ SET(GEOMImpl_HEADERS
GEOMImpl_FillingDriver.hxx GEOMImpl_FillingDriver.hxx
GEOMImpl_GlueDriver.hxx GEOMImpl_GlueDriver.hxx
GEOMImpl_PatchFaceDriver.hxx GEOMImpl_PatchFaceDriver.hxx
GEOMImpl_ShapeProximityDriver.hxx
GEOMImpl_Types.hxx GEOMImpl_Types.hxx
GEOM_GEOMImpl.hxx GEOM_GEOMImpl.hxx
GEOMImpl_ICanonicalRecognition.hxx GEOMImpl_ICanonicalRecognition.hxx
@ -261,6 +263,7 @@ SET(GEOMImpl_SOURCES
GEOMImpl_FillingDriver.cxx GEOMImpl_FillingDriver.cxx
GEOMImpl_GlueDriver.cxx GEOMImpl_GlueDriver.cxx
GEOMImpl_PatchFaceDriver.cxx GEOMImpl_PatchFaceDriver.cxx
GEOMImpl_ShapeProximityDriver.cxx
GEOMImpl_FieldDriver.cxx GEOMImpl_FieldDriver.cxx
GEOMImpl_ICanonicalRecognition.cxx GEOMImpl_ICanonicalRecognition.cxx
) )

View File

@ -84,6 +84,7 @@
#include <GEOMImpl_MeasureDriver.hxx> #include <GEOMImpl_MeasureDriver.hxx>
#include <GEOMImpl_FieldDriver.hxx> #include <GEOMImpl_FieldDriver.hxx>
#include <GEOMImpl_ConformityDriver.hxx> #include <GEOMImpl_ConformityDriver.hxx>
#include <GEOMImpl_ShapeProximityDriver.hxx>
//============================================================================= //=============================================================================
/*! /*!
@ -165,6 +166,7 @@ GEOMImpl_Gen::GEOMImpl_Gen()
TFunction_DriverTable::Get()->AddDriver(GEOMImpl_MeasureDriver::GetID(), new GEOMImpl_MeasureDriver()); TFunction_DriverTable::Get()->AddDriver(GEOMImpl_MeasureDriver::GetID(), new GEOMImpl_MeasureDriver());
TFunction_DriverTable::Get()->AddDriver(GEOMImpl_PatchFaceDriver::GetID(), new GEOMImpl_PatchFaceDriver()); TFunction_DriverTable::Get()->AddDriver(GEOMImpl_PatchFaceDriver::GetID(), new GEOMImpl_PatchFaceDriver());
TFunction_DriverTable::Get()->AddDriver(GEOMImpl_ConformityDriver::GetID(), new GEOMImpl_ConformityDriver()); TFunction_DriverTable::Get()->AddDriver(GEOMImpl_ConformityDriver::GetID(), new GEOMImpl_ConformityDriver());
TFunction_DriverTable::Get()->AddDriver(GEOMImpl_ShapeProximityDriver::GetID(), new GEOMImpl_ShapeProximityDriver());
// Field // Field
TFunction_DriverTable::Get()->AddDriver(GEOMImpl_FieldDriver::GetID(), new GEOMImpl_FieldDriver()); TFunction_DriverTable::Get()->AddDriver(GEOMImpl_FieldDriver::GetID(), new GEOMImpl_FieldDriver());

View File

@ -25,7 +25,9 @@
#include <GEOMImpl_MeasureDriver.hxx> #include <GEOMImpl_MeasureDriver.hxx>
#include <GEOMImpl_IPatchFace.hxx> #include <GEOMImpl_IPatchFace.hxx>
#include <GEOMImpl_IProximity.hxx>
#include <GEOMImpl_PatchFaceDriver.hxx> #include <GEOMImpl_PatchFaceDriver.hxx>
#include <GEOMImpl_ShapeProximityDriver.hxx>
#include <GEOMImpl_Types.hxx> #include <GEOMImpl_Types.hxx>
@ -3278,3 +3280,193 @@ void GEOMImpl_IMeasureOperations::FillErrors
} }
} }
} }
//=======================================================================
//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)
{
SetErrorCode(KO);
if (theShape1.IsNull() || theShape2.IsNull())
return NULL;
Handle(GEOM_Object) aProximityCalc = GetEngine()->AddObject(GEOM_SHAPE_PROXIMITY);
if (aProximityCalc.IsNull())
return NULL;
Handle(GEOM_Function) aProximityFuncCoarse =
aProximityCalc->AddFunction(GEOMImpl_ShapeProximityDriver::GetID(), PROXIMITY_COARSE);
//Check if the function is set correctly
if (aProximityFuncCoarse.IsNull() ||
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;
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 << ")";
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)
{
SetErrorCode(KO);
if (theShape.IsNull() ||
theCalculator.IsNull() ||
theCalculator->GetNbFunctions() <= 0 ||
theNbSamples <= 0)
return ;
Handle(GEOM_Function) aProximityFuncCoarse = theCalculator->GetFunction(1);
if (aProximityFuncCoarse.IsNull() ||
aProximityFuncCoarse->GetDriverGUID() != GEOMImpl_ShapeProximityDriver::GetID())
return ;
Handle(GEOM_Function) aShapeFunc = theShape->GetLastFunction();
if (aShapeFunc.IsNull())
return ;
GEOMImpl_IProximity aProximity(aProximityFuncCoarse);
Handle(GEOM_Function) aShape1, aShape2;
aProximity.GetShapes(aShape1, aShape2);
if (aShape1 == aShapeFunc)
aProximity.SetNbSamples(PROXIMITY_ARG_SAMPLES1, theNbSamples);
else if (aShape2 == aShapeFunc)
aProximity.SetNbSamples(PROXIMITY_ARG_SAMPLES2, theNbSamples);
//Make a Python command
GEOM::TPythonDump(aProximityFuncCoarse) << "p.setSampling(" << theShape << ", " << theNbSamples << ")";
SetErrorCode(OK);
}
//=======================================================================
//function : GetCoarseProximity
//purpose : compute coarse proximity
//=======================================================================
Standard_Real GEOMImpl_IMeasureOperations::GetCoarseProximity(Handle(GEOM_Object) theCalculator)
{
SetErrorCode(KO);
if (theCalculator.IsNull())
return NULL;
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
if (aProximityFuncCoarse.IsNull() ||
aProximityFuncCoarse->GetDriverGUID() != GEOMImpl_ShapeProximityDriver::GetID())
return NULL;
GEOMImpl_IProximity aProximity(aProximityFuncCoarse);
//Make a Python command
GEOM::TPythonDump(aProximityFuncCoarse) << "value = p.coarseProximity()";
SetErrorCode(OK);
return aProximity.GetValue();
}
//=======================================================================
//function : GetPreciseProximity
//purpose : compute precise proximity
//=======================================================================
Standard_Real GEOMImpl_IMeasureOperations::GetPreciseProximity(Handle(GEOM_Object) theCalculator)
{
SetErrorCode(KO);
if (theCalculator.IsNull())
return NULL;
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);
//Check if the functions are set correctly
if (aProximityFuncCoarse.IsNull() ||
aProximityFuncCoarse->GetDriverGUID() != GEOMImpl_ShapeProximityDriver::GetID() ||
aProximityFuncFine.IsNull() ||
aProximityFuncFine->GetDriverGUID() != GEOMImpl_ShapeProximityDriver::GetID())
return NULL;
// transfer parameters from the coarse to precise calculator
GEOMImpl_IProximity aCoarseProximity(aProximityFuncCoarse);
Handle(GEOM_Function) aShape1, aShape2;
aCoarseProximity.GetShapes(aShape1, aShape2);
if (aShape1.IsNull() || aShape2.IsNull())
return NULL;
gp_Pnt aProxPnt1, aProxPnt2;
aCoarseProximity.GetProximityPoints(aProxPnt1, aProxPnt2);
GEOMImpl_IProximity aFineProximity(aProximityFuncFine);
aFineProximity.SetShapes(aShape1, aShape2);
aFineProximity.SetProximityPoints(aProxPnt1, aProxPnt2);
// 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;
}
//Make a Python command
GEOM::TPythonDump(aProximityFuncCoarse) << "value = p.preciseProximity()";
SetErrorCode(OK);
return aFineProximity.GetValue();
}

View File

@ -244,6 +244,15 @@ class GEOMImpl_IMeasureOperations : public GEOM_IOperations {
Handle(GEOM_Object) thePoint, Handle(GEOM_Object) thePoint,
Handle(GEOM_Object) theDirection); Handle(GEOM_Object) theDirection);
// 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 GetPreciseProximity(Handle(GEOM_Object) theCalculator);
Standard_EXPORT void SetShapeSampling(Handle(GEOM_Object) theCalculator,
Handle(GEOM_Object) theShape,
const Standard_Integer theNbSamples);
private: private:
void FillErrorsSub void FillErrorsSub

View File

@ -0,0 +1,98 @@
// Copyright (C) 2022-2022 CEA/DEN, EDF R&D, OPEN CASCADE
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
#include <GEOM_Function.hxx>
#define PROXIMITY_ARG_SHAPE1 1
#define PROXIMITY_ARG_SHAPE2 2
#define PROXIMITY_ARG_SAMPLES1 3
#define PROXIMITY_ARG_SAMPLES2 4
#define PROXIMITY_ARG_POINT1 5
#define PROXIMITY_ARG_POINT2 6
#define PROXIMITY_ARG_VALUE 7
class GEOMImpl_IProximity
{
public:
GEOMImpl_IProximity(Handle(GEOM_Function) theFunction) : _func(theFunction) {}
void SetShapes(Handle(GEOM_Function) theShape1, Handle(GEOM_Function) theShape2)
{
_func->SetReference(PROXIMITY_ARG_SHAPE1, theShape1);
_func->SetReference(PROXIMITY_ARG_SHAPE2, theShape2);
}
void GetShapes(Handle(GEOM_Function)& theShape1, Handle(GEOM_Function)& theShape2) const
{
theShape1 = _func->GetReference(PROXIMITY_ARG_SHAPE1);
theShape2 = _func->GetReference(PROXIMITY_ARG_SHAPE2);
}
void SetNbSamples(const Standard_Integer thePosition, const Standard_Integer theNbSamples) const
{
_func->SetInteger(thePosition, theNbSamples);
}
Standard_Integer GetNbSamples(const Standard_Integer thePosition) const
{
return _func->GetInteger(thePosition);
}
void SetProximityPoints(const gp_Pnt& thePoint1, const gp_Pnt& thePoint2)
{
setPoint(PROXIMITY_ARG_POINT1, thePoint1);
setPoint(PROXIMITY_ARG_POINT2, thePoint2);
}
void GetProximityPoints(gp_Pnt& thePoint1, gp_Pnt& thePoint2)
{
thePoint1 = getPoint(PROXIMITY_ARG_POINT1);
thePoint2 = getPoint(PROXIMITY_ARG_POINT2);
}
void SetValue(const Standard_Real theValue)
{
_func->SetReal(PROXIMITY_ARG_VALUE, theValue);
}
Standard_Real GetValue() const
{
return _func->GetReal(PROXIMITY_ARG_VALUE);
}
private:
void setPoint(const Standard_Integer thePosition, const gp_Pnt& thePoint)
{
Handle(TColStd_HArray1OfReal) aCoords = new TColStd_HArray1OfReal(1, 3);
aCoords->SetValue(1, thePoint.X());
aCoords->SetValue(2, thePoint.Y());
aCoords->SetValue(3, thePoint.Z());
_func->SetRealArray(thePosition, aCoords);
}
gp_Pnt getPoint(const Standard_Integer thePosition)
{
Handle(TColStd_HArray1OfReal) aCoords = _func->GetRealArray(thePosition);
return gp_Pnt(aCoords->Value(1), aCoords->Value(2), aCoords->Value(3));
}
private:
Handle(GEOM_Function) _func;
};

View File

@ -0,0 +1,295 @@
// Copyright (C) 2022-2022 CEA/DEN, EDF R&D, OPEN CASCADE
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
#include <GEOMImpl_ShapeProximityDriver.hxx>
#include <GEOMImpl_IProximity.hxx>
#include <GEOMImpl_Types.hxx>
#include <BRep_Tool.hxx>
#include <BRepAdaptor_Curve.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <BRepExtrema_ShapeProximity.hxx>
#include <BRepMesh_IncrementalMesh.hxx>
#include <Extrema_ExtPC.hxx>
#include <Extrema_ExtPS.hxx>
#include <Extrema_GenLocateExtCS.hxx>
#include <Extrema_GenLocateExtSS.hxx>
#include <Extrema_LocateExtCC.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
namespace {
static void tessellateShape(const TopoDS_Shape& theShape)
{
Standard_Boolean isTessellate = Standard_False;
TopLoc_Location aLoc;
for (TopExp_Explorer anExp(theShape, TopAbs_FACE); anExp.More() && !isTessellate; anExp.Next())
{
Handle(Poly_Triangulation) aTria = BRep_Tool::Triangulation(TopoDS::Face(anExp.Value()), aLoc);
isTessellate = aTria.IsNull();
}
for (TopExp_Explorer anExp(theShape, TopAbs_EDGE); anExp.More() && !isTessellate; anExp.Next())
{
Handle(Poly_Polygon3D) aPoly = BRep_Tool::Polygon3D(TopoDS::Edge(anExp.Value()), aLoc);
isTessellate = aPoly.IsNull();
}
if (isTessellate)
{
BRepMesh_IncrementalMesh aMesher(theShape, 0.1);
Standard_ProgramError_Raise_if(!aMesher.IsDone(), "Meshing failed");
}
}
static Standard_Real paramOnCurve(const BRepAdaptor_Curve& theCurve, const gp_Pnt& thePoint, const Standard_Real theTol)
{
Extrema_ExtPC aParamSearch(thePoint, theCurve, theCurve.FirstParameter(), theCurve.LastParameter());
if (aParamSearch.IsDone())
{
Standard_Integer anIndMin = 0, aNbExt = aParamSearch.NbExt();
Standard_Real aSqDistMin = RealLast();
for (Standard_Integer i = 1; i <= aNbExt; ++i)
{
if (aParamSearch.SquareDistance(i) < aSqDistMin)
{
anIndMin = i;
aSqDistMin = aParamSearch.SquareDistance(i);
}
}
if (anIndMin != 0 && aSqDistMin <= theTol * theTol)
{
return aParamSearch.Point(anIndMin).Parameter();
}
}
return 0.5 * (theCurve.FirstParameter() + theCurve.LastParameter());
}
static void paramsOnSurf(const BRepAdaptor_Surface& theSurf, const gp_Pnt& thePoint, const Standard_Real theTol,
Standard_Real& theU, Standard_Real& theV)
{
Extrema_ExtPS aParamSearch(thePoint, theSurf, Precision::PConfusion(), Precision::PConfusion());
if (aParamSearch.IsDone())
{
Standard_Integer anIndMin = 0, aNbExt = aParamSearch.NbExt();
Standard_Real aSqDistMin = RealLast();
for (Standard_Integer i = 1; i <= aNbExt; ++i)
{
if (aParamSearch.SquareDistance(i) < aSqDistMin)
{
anIndMin = i;
aSqDistMin = aParamSearch.SquareDistance(i);
}
}
if (anIndMin != 0 && aSqDistMin <= theTol * theTol)
{
return aParamSearch.Point(anIndMin).Parameter(theU, theV);
}
}
theU = 0.5 * (theSurf.FirstUParameter() + theSurf.LastUParameter());
theV = 0.5 * (theSurf.FirstVParameter() + theSurf.LastVParameter());
}
static Standard_Real extremaEE(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2,
gp_Pnt& thePoint1, gp_Pnt& thePoint2)
{
BRepAdaptor_Curve aCurve1(theEdge1);
BRepAdaptor_Curve aCurve2(theEdge2);
Standard_Real aU1 = paramOnCurve(aCurve1, thePoint1, BRep_Tool::Tolerance(theEdge1));
Standard_Real aU2 = paramOnCurve(aCurve2, thePoint2, BRep_Tool::Tolerance(theEdge2));
Standard_Real aValue = -1.0;
Extrema_LocateExtCC anExtr(aCurve1, aCurve2, aU1, aU2);
if (anExtr.IsDone())
{
aValue = Sqrt(anExtr.SquareDistance());
Extrema_POnCurv aP1, aP2;
anExtr.Point(aP1, aP2);
thePoint1 = aP1.Value();
thePoint2 = aP2.Value();
}
return aValue;
}
static Standard_Real extremaEF(const TopoDS_Edge& theEdge, const TopoDS_Face& theFace,
gp_Pnt& thePonE, gp_Pnt& thePonF)
{
BRepAdaptor_Curve aCurve(theEdge);
BRepAdaptor_Surface aSurf(theFace);
Standard_Real aP = paramOnCurve(aCurve, thePonE, BRep_Tool::Tolerance(theEdge));
Standard_Real aU, aV;
paramsOnSurf(aSurf, thePonF, BRep_Tool::Tolerance(theFace), aU, aV);
Standard_Real aValue = -1.0;
Extrema_GenLocateExtCS anExtr(aCurve, aSurf, aP, aU, aV, Precision::PConfusion(), Precision::PConfusion());
if (anExtr.IsDone())
{
aValue = Sqrt(anExtr.SquareDistance());
thePonE = anExtr.PointOnCurve().Value();
thePonF = anExtr.PointOnSurface().Value();
}
return aValue;
}
static Standard_Real extremaFF(const TopoDS_Face& theFace1, const TopoDS_Face& theFace2,
gp_Pnt& thePoint1, gp_Pnt& thePoint2)
{
BRepAdaptor_Surface aSurf1(theFace1);
BRepAdaptor_Surface aSurf2(theFace2);
Standard_Real aU1, aV1;
paramsOnSurf(aSurf1, thePoint1, BRep_Tool::Tolerance(theFace1), aU1, aV1);
Standard_Real aU2, aV2;
paramsOnSurf(aSurf2, thePoint2, BRep_Tool::Tolerance(theFace2), aU2, aV2);
Standard_Real aValue = -1.0;
Extrema_GenLocateExtSS anExtr(aSurf1, aSurf2, aU1, aV1, aU2, aV2, Precision::PConfusion(), Precision::PConfusion());
if (anExtr.IsDone())
{
aValue = Sqrt(anExtr.SquareDistance());
thePoint1 = anExtr.PointOnS1().Value();
thePoint2 = anExtr.PointOnS2().Value();
}
return aValue;
}
}
//=======================================================================
//function : GetID
//purpose :
//=======================================================================
const Standard_GUID& GEOMImpl_ShapeProximityDriver::GetID()
{
static Standard_GUID aShapeProximityDriver("1C3449A6-E4EB-407D-B623-89261C4BA785");
return aShapeProximityDriver;
}
//=======================================================================
//function : Execute
//purpose :
//=======================================================================
Standard_Integer GEOMImpl_ShapeProximityDriver::Execute(Handle(TFunction_Logbook)& log) const
{
if (Label().IsNull())
return 0;
Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
GEOMImpl_IProximity aProximity(aFunction);
Handle(GEOM_Function) aShapeFunc1, aShapeFunc2;
aProximity.GetShapes(aShapeFunc1, aShapeFunc2);
if (aShapeFunc1.IsNull() || aShapeFunc2.IsNull())
return 0;
TopoDS_Shape aShape1 = aShapeFunc1->GetValue();
TopoDS_Shape aShape2 = aShapeFunc2->GetValue();
Standard_Real aValue = -1.0;
if (aFunction->GetType() == PROXIMITY_COARSE)
{
// tessellate shapes if there is no mesh exists
tessellateShape(aShape1);
tessellateShape(aShape2);
// compute proximity basing of the tessellation
BRepExtrema_ShapeProximity aCalcProx;
aCalcProx.LoadShape1(aShape1);
aCalcProx.LoadShape2(aShape2);
aCalcProx.SetNbSamples1(aProximity.GetNbSamples(PROXIMITY_ARG_SAMPLES1));
aCalcProx.SetNbSamples2(aProximity.GetNbSamples(PROXIMITY_ARG_SAMPLES2));
aCalcProx.Perform();
if (aCalcProx.IsDone())
{
aValue = aCalcProx.Proximity();
aProximity.SetProximityPoints(aCalcProx.ProximityPoint1(),
aCalcProx.ProximityPoint2());
}
else
Standard_ConstructionError::Raise("Failed to compute coarse proximity");
}
else if (aFunction->GetType() == PROXIMITY_PRECISE)
{
TopAbs_ShapeEnum aType1 = aShape1.ShapeType();
TopAbs_ShapeEnum aType2 = aShape2.ShapeType();
gp_Pnt aP1, aP2;
aProximity.GetProximityPoints(aP1, aP2);
if (aType1 == TopAbs_EDGE)
{
if (aType2 == TopAbs_EDGE)
aValue = extremaEE(TopoDS::Edge(aShape1), TopoDS::Edge(aShape2), aP1, aP2);
else if (aType2 == TopAbs_FACE)
aValue = extremaEF(TopoDS::Edge(aShape1), TopoDS::Face(aShape2), aP1, aP2);
}
else if (aType1 == TopAbs_FACE)
{
if (aType2 == TopAbs_EDGE)
aValue = extremaEF(TopoDS::Edge(aShape2), TopoDS::Face(aShape1), aP2, aP1);
else if (aType2 == TopAbs_FACE)
aValue = extremaFF(TopoDS::Face(aShape1), TopoDS::Face(aShape2), aP1, aP2);
}
if (aValue >= 0)
aProximity.SetProximityPoints(aP1, aP2);
else
Standard_ConstructionError::Raise("Failed to compute precise proximity");
}
else
{
Standard_ConstructionError::Raise("incorrect algorithm");
}
aProximity.SetValue(aValue);
log->SetTouched(Label());
return 1;
}
//=======================================================================
//function : GetCreationInformation
//purpose : Returns a name of creation operation and names and values of creation parameters
//=======================================================================
bool GEOMImpl_ShapeProximityDriver::GetCreationInformation(
std::string& theOperationName,
std::vector<GEOM_Param>& theParams)
{
if (Label().IsNull())
return false;
Handle(GEOM_Function) aFunc = GEOM_Function::GetFunction(Label());
GEOMImpl_IProximity aProxFunc(aFunc);
Handle(GEOM_Function) aShape1, aShape2;
aProxFunc.GetShapes(aShape1, aShape2);
if (aFunc->GetType() == PROXIMITY_COARSE)
theOperationName = "PROXIMITY_COARSE";
else if (aFunc->GetType() == PROXIMITY_PRECISE)
theOperationName = "PROXIMITY_PRECISE";
AddParam(theParams, "Shape1", aShape1);
AddParam(theParams, "Shape2", aShape2);
return false;
}
IMPLEMENT_STANDARD_RTTIEXT(GEOMImpl_ShapeProximityDriver, GEOM_BaseDriver)

View File

@ -0,0 +1,45 @@
// Copyright (C) 2022-2022 CEA/DEN, EDF R&D, OPEN CASCADE
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
#ifndef _GEOMImpl_ShapeProximityDriver_HeaderFile
#define _GEOMImpl_ShapeProximityDriver_HeaderFile
#include <GEOM_BaseDriver.hxx>
DEFINE_STANDARD_HANDLE(GEOMImpl_ShapeProximityDriver, GEOM_BaseDriver)
class GEOMImpl_ShapeProximityDriver : public GEOM_BaseDriver {
public:
Standard_EXPORT GEOMImpl_ShapeProximityDriver() {}
Standard_EXPORT virtual Standard_Integer Execute(Handle(TFunction_Logbook)& log) const;
Standard_EXPORT virtual void Validate(Handle(TFunction_Logbook)&) const {}
Standard_EXPORT Standard_Boolean MustExecute(const Handle(TFunction_Logbook)&) const { return Standard_True; }
Standard_EXPORT static const Standard_GUID& GetID();
Standard_EXPORT ~GEOMImpl_ShapeProximityDriver() {}
Standard_EXPORT virtual
bool GetCreationInformation(std::string& theOperationName,
std::vector<GEOM_Param>& params);
DEFINE_STANDARD_RTTIEXT(GEOMImpl_ShapeProximityDriver, GEOM_BaseDriver)
};
#endif

View File

@ -125,6 +125,7 @@
#define GEOM_PATCH_FACE 60 #define GEOM_PATCH_FACE 60
#define GEOM_SHAPE_PROXIMITY 61
#define GEOM_CHECKCONFORMITY 62 #define GEOM_CHECKCONFORMITY 62
//GEOM_Function types //GEOM_Function types
@ -365,6 +366,10 @@
#define VERTEX_BY_INDEX 5 #define VERTEX_BY_INDEX 5
#define CURVATURE_VEC_MEASURE 6 #define CURVATURE_VEC_MEASURE 6
// Proximity algorithms
#define PROXIMITY_COARSE 1
#define PROXIMITY_PRECISE 2
#define GROUP_FUNCTION 1 #define GROUP_FUNCTION 1
// Curve constructor type // Curve constructor type

View File

@ -1443,3 +1443,97 @@ void GEOM_IMeasureOperations_i::ConvertToList(const GEOM::GEOM_IMeasureOperation
theListOfResults.push_back(aCheck); theListOfResults.push_back(aCheck);
} }
} }
//=============================================================================
/*!
* ShapeProximityCalculator
*/
//=============================================================================
GEOM::GEOM_Object_ptr GEOM_IMeasureOperations_i::ShapeProximityCalculator(GEOM::GEOM_Object_ptr theShape1,
GEOM::GEOM_Object_ptr theShape2)
{
GEOM::GEOM_Object_var anEmptyCalc;
//Set a not done flag
GetOperations()->SetNotDone();
//Get the reference shape
Handle(::GEOM_Object) aShape1 = GetObjectImpl(theShape1);
Handle(::GEOM_Object) aShape2 = GetObjectImpl(theShape2);
if (aShape1.IsNull() || aShape2.IsNull())
return anEmptyCalc._retn();
Handle(::GEOM_Object) aCalculator = GetOperations()->ShapeProximityCalculator(aShape1, aShape2);
if (!GetOperations()->IsDone() || aCalculator.IsNull())
return anEmptyCalc._retn();
return GetObject(aCalculator);
}
//=============================================================================
/*!
* SetShapeSampling
*/
//=============================================================================
void GEOM_IMeasureOperations_i::SetShapeSampling(GEOM::GEOM_Object_ptr theCalculator,
GEOM::GEOM_Object_ptr theShape,
long theNbSamples)
{
//Set a not done flag
GetOperations()->SetNotDone();
//Get the proximity calculator
Handle(::GEOM_Object) aCalc = GetObjectImpl(theCalculator);
if (aCalc.IsNull())
return ;
//Get the reference shape
Handle(::GEOM_Object) aShape = GetObjectImpl(theShape);
if (aShape.IsNull())
return ;
GetOperations()->SetShapeSampling(aCalc, aShape, theNbSamples);
}
//=============================================================================
/*!
* GetCoarseProximity
*/
//=============================================================================
CORBA::Double GEOM_IMeasureOperations_i::GetCoarseProximity(GEOM::GEOM_Object_ptr theCalculator)
{
//Set a not done flag
GetOperations()->SetNotDone();
//Get the reference shape
Handle(::GEOM_Object) aCalc = GetObjectImpl(theCalculator);
if (aCalc.IsNull())
return -1.0;
Standard_Real aProximity = GetOperations()->GetCoarseProximity(aCalc);
if (!GetOperations()->IsDone())
return -1.0;
return aProximity;
}
//=============================================================================
/*!
* GetPreciseProximity
*/
//=============================================================================
CORBA::Double GEOM_IMeasureOperations_i::GetPreciseProximity(GEOM::GEOM_Object_ptr theCalculator)
{
//Set a not done flag
GetOperations()->SetNotDone();
//Get the reference shape
Handle(::GEOM_Object) aCalc = GetObjectImpl(theCalculator);
if (aCalc.IsNull())
return -1.0;
Standard_Real aProximity = GetOperations()->GetPreciseProximity(aCalc);
if (!GetOperations()->IsDone())
return -1.0;
return aProximity;
}

View File

@ -191,6 +191,15 @@ class GEOM_I_EXPORT GEOM_IMeasureOperations_i :
CORBA::Double UpdateTolerance(GEOM::GEOM_Object_ptr theShape); CORBA::Double UpdateTolerance(GEOM::GEOM_Object_ptr theShape);
// Methods to compute proximity between two shapes
GEOM::GEOM_Object_ptr ShapeProximityCalculator (GEOM::GEOM_Object_ptr theShape1,
GEOM::GEOM_Object_ptr theShape2);
void SetShapeSampling(GEOM::GEOM_Object_ptr theCalculator,
GEOM::GEOM_Object_ptr theShape,
long theNbSamples);
CORBA::Double GetCoarseProximity(GEOM::GEOM_Object_ptr theCalculator);
CORBA::Double GetPreciseProximity(GEOM::GEOM_Object_ptr theCalculator);
::GEOMImpl_IMeasureOperations* GetOperations() ::GEOMImpl_IMeasureOperations* GetOperations()
{ return (::GEOMImpl_IMeasureOperations*)GetImpl(); } { return (::GEOMImpl_IMeasureOperations*)GetImpl(); }

View File

@ -73,6 +73,7 @@ SET(_python_SCRIPTS
gsketcher.py gsketcher.py
canonicalrecognition.py canonicalrecognition.py
conformity.py conformity.py
proximity.py
) )
# Advanced scripts # Advanced scripts

View File

@ -262,6 +262,7 @@ import functools
from salome.geom.gsketcher import Sketcher3D, Sketcher2D, Polyline2D from salome.geom.gsketcher import Sketcher3D, Sketcher2D, Polyline2D
from salome.geom.canonicalrecognition import CanonicalRecognition from salome.geom.canonicalrecognition import CanonicalRecognition
from salome.geom.conformity import CheckConformity from salome.geom.conformity import CheckConformity
from salome.geom.proximity import ShapeProximity
# In case the omniORBpy EnumItem class does not fully support Python 3 # In case the omniORBpy EnumItem class does not fully support Python 3
# (for instance in version 4.2.1-2), the comparison ordering methods must be # (for instance in version 4.2.1-2), the comparison ordering methods must be
@ -14056,6 +14057,21 @@ class geomBuilder(GEOM._objref_GEOM_Gen):
conf = CheckConformity (shape, self) conf = CheckConformity (shape, self)
return conf return conf
## Obtain a shape proximity calculator
# @return An instance of @ref proximity.ShapeProximity "ShapeProximity" interface
#
# @ref tui_proximity_page "Example"
def ShapeProximity (self):
"""
Obtain a shape proximity calculator.
Example of usage:
prox = geompy.ShapeProximity()
value = prox.proximity(shape1, shape2)
"""
prox = ShapeProximity (self)
return prox
# end of l2_testing # end of l2_testing
## @} ## @}

View File

@ -0,0 +1,91 @@
# -*- coding: iso-8859-1 -*-
# Copyright (C) 2022-2022 CEA/DEN, EDF R&D, OPEN CASCADE
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
## @defgroup proximity ShapeProximity - tool to check the proximity distance between two shapes
# @{
# @details
# The tool provides the user a possibility to compute the proximity distance between two shapes:
# * a minimal diameter of a tube containing both edges (for edge-edge proximity);
# * a minimal thickness of a shell containing both faces (for face-face proximity).
#
# In other words, this tool calculate maximal of all possible distances between pair of objects.
# It is supported to compute distance between two edges or between two faces.
# Other combinations of shapes are prohibited.
# @}
"""
\namespace geompy
\brief ShapeProximity interface
"""
## A class to compute proximity value between two shapes.
# Use geompy.ShapeProximity() method to obtain an instance of this class.
#
# @ref tui_proximity_page "Example"
# @ingroup proximity
class ShapeProximity():
"""
ShapeProximity interface.
Example of usage:
prox = geompy.ShapeProximity()
value = prox.proximity(shape1, shape2)
"""
def __init__(self, geompyD):
self.myCommand = "ShapeProximity"
self.myOp = geompyD.GetIMeasureOperations()
pass
## Computes proximity between two shapes of the same type
def proximity(self, shape1, shape2):
self.setShapes(shape1, shape2)
self.coarseProximity()
return self.preciseProximity()
pass
## Customize object with the input shapes
def setShapes(self, shape1, shape2):
self.myProximityValue = None
from salome.geom.geomBuilder import RaiseIfFailed
self.myCalc = self.myOp.ShapeProximityCalculator(shape1, shape2)
RaiseIfFailed(self.myCommand, self.myOp)
pass
## Define the minimal number of sample points for the given shape,
# which should be used for raw computation of proximity value
def setSampling(self, shape, nbSamples):
self.myOp.SetShapeSampling(self.myCalc, shape, nbSamples)
pass
## Find rough proximity value based on polygon/tessellation representation
def coarseProximity(self):
from salome.geom.geomBuilder import RaiseIfFailed
self.myProximityValue = self.myOp.GetCoarseProximity(self.myCalc)
RaiseIfFailed(self.myCommand, self.myOp)
return self.myProximityValue
pass
## Find precise proximity value based on exact shapes
def preciseProximity(self):
from salome.geom.geomBuilder import RaiseIfFailed
self.myProximityValue = self.myOp.GetPreciseProximity(self.myCalc)
RaiseIfFailed(self.myCommand, self.myOp)
return self.myProximityValue
pass

View File

@ -0,0 +1,60 @@
# Shape Proximity between edges
import math
import salome
salome.salome_init_without_session()
import GEOM
from salome.geom import geomBuilder
geompy = geomBuilder.New()
O = geompy.MakeVertex(0, 0, 0)
OX = geompy.MakeVectorDXDYDZ(1, 0, 0)
OY = geompy.MakeVectorDXDYDZ(0, 1, 0)
OZ = geompy.MakeVectorDXDYDZ(0, 0, 1)
# create arc and segment
Vertex_1 = geompy.MakeVertex(0, 0, -1)
Vertex_2 = geompy.MakeVertex(1, 0, 0)
Vertex_3 = geompy.MakeVertex(0, 0, 1)
Arc_1 = geompy.MakeArc(Vertex_1, Vertex_2, Vertex_3)
Arc_1_vertex_2 = geompy.GetSubShape(Arc_1, [2])
Edge_1 = geompy.MakeEdgeOnCurveByLength(Arc_1, 3, Arc_1_vertex_2)
Edge_2 = geompy.MakeEdge(Vertex_1, Vertex_3)
shape1 = Edge_1
shape2 = Edge_2
# perform proximity calculation with the default parameters
p1 = geompy.ShapeProximity()
proximity1 = p1.proximity(shape1, shape2)
# perform proximity calculation with custom parameters
p2 = geompy.ShapeProximity()
p2.setShapes(shape1, shape2)
p2.setSampling(shape1, 100) # number of sample points for the first shape
p2.setSampling(shape2, 40) # number of sample points for the second shape
proximity2_coarse = p2.coarseProximity()
proximity2_fine = p2.preciseProximity()
assert(math.fabs(proximity1 - proximity2_fine) < 1.e-7)
assert(math.fabs(proximity2_coarse - 0.9974949866) < 1.e-7)
assert(math.fabs(proximity2_fine - 1) < 1.e-7)
# move second edge and check proximity
Translation_1 = geompy.MakeTranslation(Edge_2, 0.3, 0, 0)
shape2 = Translation_1
# perform proximity calculation with the default parameters
p1 = geompy.ShapeProximity()
proximity1 = p1.proximity(shape1, shape2)
# perform proximity calculation with custom parameters
p2 = geompy.ShapeProximity()
p2.setShapes(shape1, shape2)
p2.setSampling(shape1, 100) # number of sample points for the first shape
p2.setSampling(shape2, 40) # number of sample points for the second shape
proximity2_coarse = p2.coarseProximity()
proximity2_fine = p2.preciseProximity()
assert(math.fabs(proximity1 - 0.7) < 1.e-7)
assert(math.fabs(proximity2_fine - 0.7) < 1.e-7)

View File

@ -0,0 +1,43 @@
# Shape Proximity between faces
import math
import salome
salome.salome_init_without_session()
import GEOM
from salome.geom import geomBuilder
geompy = geomBuilder.New()
O = geompy.MakeVertex(0, 0, 0)
OX = geompy.MakeVectorDXDYDZ(1, 0, 0)
OY = geompy.MakeVectorDXDYDZ(0, 1, 0)
OZ = geompy.MakeVectorDXDYDZ(0, 0, 1)
# create 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_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)
shape1 = Face_1
shape2 = Translation_1
# perform proximity calculation with the default parameters
p1 = geompy.ShapeProximity()
proximity1 = p1.proximity(shape1, shape2)
# perform proximity calculation with custom parameters
p2 = geompy.ShapeProximity()
p2.setShapes(shape1, shape2)
p2.setSampling(shape1, 100) # number of sample points for the first shape
p2.setSampling(shape2, 40) # number of sample points for the second shape
proximity2_coarse = p2.coarseProximity()
proximity2_fine = p2.preciseProximity()
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)

View File

@ -27,5 +27,7 @@ IF(${OpenCASCADE_VERSION}.${OpenCASCADE_SP_VERSION} VERSION_GREATER "7.5.3.3")
test_point_cloud_on_face.py test_point_cloud_on_face.py
test_CR.py test_CR.py
test_conformity.py test_conformity.py
test_proximity_edge_edge.py
test_proximity_face_face.py
) )
ENDIF() ENDIF()