[bos #29473] [EDF] (2022-T1) Advanced geometry features: conformity of non holed-face

This commit is contained in:
Alexey SOZINOV 2022-04-22 13:12:04 +03:00
parent 1b56fc0813
commit 2d61a5f020
15 changed files with 1631 additions and 9 deletions

View File

@ -59,13 +59,14 @@ ENDIF(WIN32)
ADD_CUSTOM_TARGET(usr_docs ${CMAKE_COMMAND} -E make_directory tmp
COMMAND ${CMAKE_COMMAND} -E make_directory tmp1
COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/geomBuilder.py ${CMAKE_SOURCE_DIR}/src/GEOM_SWIG/geomBuilder.py
COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/gsketcher.py ${CMAKE_SOURCE_DIR}/src/GEOM_SWIG/gsketcher.py
COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/geomtools.py ${CMAKE_SOURCE_DIR}/src/GEOM_PY/geomtools.py
COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/sketcher.py ${CMAKE_SOURCE_DIR}/src/GEOM_PY/sketcher.py
COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/structelem.py ${CMAKE_SOURCE_DIR}/src/GEOM_PY/structelem/__init__.py
COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/parts.py ${CMAKE_SOURCE_DIR}/src/GEOM_PY/structelem/parts.py
COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/orientation.py ${CMAKE_SOURCE_DIR}/src/GEOM_PY/structelem/orientation.py
COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/geomBuilder.py ${CMAKE_SOURCE_DIR}/src/GEOM_SWIG/geomBuilder.py
COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/gsketcher.py ${CMAKE_SOURCE_DIR}/src/GEOM_SWIG/gsketcher.py
COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/CheckConformity.py ${CMAKE_SOURCE_DIR}/src/GEOM_SWIG/CheckConformity.py
COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/geomtools.py ${CMAKE_SOURCE_DIR}/src/GEOM_PY/geomtools.py
COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/sketcher.py ${CMAKE_SOURCE_DIR}/src/GEOM_PY/sketcher.py
COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/structelem.py ${CMAKE_SOURCE_DIR}/src/GEOM_PY/structelem/__init__.py
COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/parts.py ${CMAKE_SOURCE_DIR}/src/GEOM_PY/structelem/parts.py
COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/orientation.py ${CMAKE_SOURCE_DIR}/src/GEOM_PY/structelem/orientation.py
COMMAND ${plugins_cmd}
COMMAND ${DOXYGEN_EXECUTABLE} doxyfile_tui
COMMAND ${DOXYGEN_EXECUTABLE} doxyfile_py
@ -77,7 +78,7 @@ ADD_CUSTOM_TARGET(usr_docs ${CMAKE_COMMAND} -E make_directory tmp
)
INSTALL(CODE "EXECUTE_PROCESS(COMMAND \"${CMAKE_COMMAND}\" --build ${PROJECT_BINARY_DIR} --target usr_docs)")
INSTALL(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/GEOM DESTINATION ${SALOME_INSTALL_DOC}/gui)
INSTALL(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} DESTINATION ${SALOME_INSTALL_DOC}/gui)
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/static/SALOME_BOA_PA.pdf DESTINATION ${SALOME_INSTALL_DOC}/gui/GEOM)
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/static/ExtractAndRebuild.pdf DESTINATION ${SALOME_INSTALL_DOC}/gui/GEOM)
INSTALL(FILES input/geompy_migration.doc input/tui_auto_completion_documentation.doc input/tui_execution_distribution.doc DESTINATION ${SALOME_INSTALL_DOC}/gui/GEOM/input)

View File

@ -4716,6 +4716,91 @@ module GEOM
*/
double MinSurfaceCurvatureByPoint (in GEOM_Object theShape, in GEOM_Object thePoint);
//! Methods and structure for implement CheckConformity tool
/*!
* \brief Structure for store shapes from failed checks.
* If failed check on small edges, then second shape is null
*/
struct PairOfShape
{
GEOM_Object first;
GEOM_Object second;
};
/*!
* \brief Structure for store result of check
* store type of check as number and failed shapes
*/
struct CheckResult
{
long type;
PairOfShape failedShapes;
};
typedef sequence<PairOfShape> SequenceOfPairOfShape;
typedef sequence<CheckResult> CheckResults;
/*!
* \brief Perform analyse of shape and return all failed checks.
*
* \param theShape Shape for check.
*/
CheckResults checkConformityShape(in GEOM_Object theShape);
/*!
* \brief Find all self-intersected 2D curves.
*
* \param theResults result of check - list of failed checks and sub-shapes.
*/
SequenceOfPairOfShape selfIntersected2D(in CheckResults theResults);
/*!
* \brief Find pairs of interfering sub-shapes, by default all pairs of interfering shapes are returned.
* Avaliable types:
* - vertices touched by tolerance;
* - vertex touching an edge in the inner point;
* - vertex lying on the inner point of a face;
* - edges intersecting by inner points;
* - edge touching/intersecting face in the inner point;
* - faces intersection by inner point
*
* \param theResults result of check - list of failed checks and sub-shapes.
* \param theShapeType1 Type of shape.
* \param theShapeType2 Type of shape.
*/
SequenceOfPairOfShape interferingSubshapes(in CheckResults theResults,
in long theShapeType1, in long theShapeType2);
/*!
* \brief Find edges, which are fully covered by tolerances of vertices.
*
* \param theResults result of check - list of failed checks and sub-shapes.
*/
ListOfGO smallEdges(in CheckResults theResults);
/*!
* \brief find remote objects (sub-shape on a shape).
* Avaliable types:
* - vertex far from edge;
* - vertex far from face;
* - edge far from face
*
* \param theShape Shape for check.
* \param theShapeType Type of shape.
* \param theSubShapeType Type of sub-shape.
* \param theTolerance tolerance, by default used tolerance of sub-shape.
*/
SequenceOfPairOfShape distantShapes(in GEOM_Object theShape, in long theShapeType,
in long theSubShapeType, in double theTolerance);
/*!
* \brief Compute possible tolerance for the shape, minimize tolerance of shape as well
* as tolerance of sub-shapes as much as possible
*
* \param theShape Shape for update.
*/
double updateTolerance(in GEOM_Object theShape);
};
// # GEOM_IGroupOperations:
@ -4907,7 +4992,7 @@ module GEOM
boolean Tesselate(in GEOM_Object shape, in double linearDeflection,
in boolean isRelative, in double angularDeflection);
};
// # GEOM_Gen:
/*!
* \brief Interface to access other GEOM interfaces.

View File

@ -119,6 +119,7 @@ SET(GEOMImpl_HEADERS
GEOMImpl_IPipePath.hxx
GEOMImpl_IRevolution.hxx
GEOMImpl_IMeasure.hxx
GEOMImpl_IConformity.hxx
GEOMImpl_IShapes.hxx
GEOMImpl_IShapeExtend.hxx
GEOMImpl_IFilling.hxx
@ -155,6 +156,7 @@ SET(GEOMImpl_HEADERS
GEOMImpl_BlockDriver.hxx
GEOMImpl_Block6Explorer.hxx
GEOMImpl_MeasureDriver.hxx
GEOMImpl_ConformityDriver.hxx
GEOMImpl_PolylineDriver.hxx
GEOMImpl_PolylineDumper.hxx
GEOMImpl_CircleDriver.hxx
@ -202,6 +204,7 @@ SET(GEOMImpl_SOURCES
GEOMImpl_ITestOperations.cxx
GEOMImpl_IPolyline2D.cxx
GEOMImpl_ITransferData.cxx
GEOMImpl_IConformity.cxx
GEOMImpl_Gen.cxx
GEOMImpl_PointDriver.cxx
GEOMImpl_VectorDriver.cxx
@ -230,6 +233,7 @@ SET(GEOMImpl_SOURCES
GEOMImpl_BlockDriver.cxx
GEOMImpl_Block6Explorer.cxx
GEOMImpl_MeasureDriver.cxx
GEOMImpl_ConformityDriver.cxx
GEOMImpl_PolylineDriver.cxx
GEOMImpl_PolylineDumper.cxx
GEOMImpl_CircleDriver.cxx

View File

@ -0,0 +1,385 @@
// Copyright (C) 2013-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_ConformityDriver.hxx"
// internal includes
#include "GEOMImpl_IConformity.hxx"
// KERNEL includes
#include <utilities.h>
#include <Basics_Utils.hxx>
// GEOM includes
#include "GEOM_Function.hxx"
#include "GEOMImpl_Types.hxx"
#include <BOPAlgo_ArgumentAnalyzer.hxx>
#include <BRepTools.hxx>
#include <BRepTools_ReShape.hxx>
#include <BRepLib.hxx>
#include <BRep_Tool.hxx>
#include <TopExp_Explorer.hxx>
#include <GEOMUtils.hxx>
#include <TColStd_HArray2OfInteger.hxx>
namespace
{
//=======================================================================
//function : GetPairsOfFaultyShapes
//purpose :
//=======================================================================
NCollection_List<std::pair<TopoDS_Shape, TopoDS_Shape>> GetPairsOfFaultyShapes(
const BOPAlgo_ArgumentAnalyzer& theAnalyzer,
const BOPAlgo_CheckStatus theErrorStatus)
{
NCollection_List<std::pair<TopoDS_Shape, TopoDS_Shape>> aResList;
const BOPAlgo_ListOfCheckResult& aResult = theAnalyzer.GetCheckResult();
BOPAlgo_ListIteratorOfListOfCheckResult anIt(aResult);
for (; anIt.More(); anIt.Next())
{
if (anIt.Value().GetCheckStatus() == theErrorStatus)
{
auto aFaultyShapes = anIt.Value().GetFaultyShapes1();
aResList.Append({ aFaultyShapes.First(),
aFaultyShapes.Size() == 1 ? TopoDS_Shape() : aFaultyShapes.Last() });
}
}
return aResList;
}
//=======================================================================
//function : GetListOfSmallEdges
//purpose :
//=======================================================================
TopTools_ListOfShape GetListOfSmallEdges(const BOPAlgo_ArgumentAnalyzer& theAnalyzer)
{
TopTools_ListOfShape aResList;
const BOPAlgo_ListOfCheckResult& aResult = theAnalyzer.GetCheckResult();
BOPAlgo_ListIteratorOfListOfCheckResult anIt(aResult);
for (; anIt.More(); anIt.Next())
{
if (anIt.Value().GetCheckStatus() == BOPAlgo_CheckStatus::BOPAlgo_TooSmallEdge)
{
auto aFaultyShapes = anIt.Value().GetFaultyShapes1();
aResList.Append(aFaultyShapes.First());
}
}
return aResList;
}
//=======================================================================
//function : ConvertShapesToIndices
//purpose : Convert sub-shapes of shapes to sequence of indices
//=======================================================================
Handle(TColStd_HArray1OfInteger) ConvertShapesToIndices(const TopoDS_Shape& theShape,
const TopTools_ListOfShape& theShapes)
{
Handle(TColStd_HArray1OfInteger) aSeqOfIDs = new TColStd_HArray1OfInteger(1, theShapes.Size());
TopTools_IndexedMapOfShape anIndices;
TopExp::MapShapes(theShape, anIndices);
TopTools_ListIteratorOfListOfShape itSub(theShapes);
for (int index = 1; itSub.More(); itSub.Next(), ++index)
{
int id = anIndices.FindIndex(itSub.Value());
aSeqOfIDs->SetValue(index, id);
}
return aSeqOfIDs;
}
//=======================================================================
//function : ConvertShapesToIndices
//purpose : Convert list of pair shapes to sequence of indices
//=======================================================================
Handle(TColStd_HArray2OfInteger) ConvertShapesToIndices(
const TopoDS_Shape& theShape,
const NCollection_List<std::pair<TopoDS_Shape, TopoDS_Shape>>& theShapes)
{
Handle(TColStd_HArray2OfInteger) aSeqOfIDs = new TColStd_HArray2OfInteger(1, theShapes.Size(), 1, 2);
TopTools_IndexedMapOfShape anIndices;
TopExp::MapShapes(theShape, anIndices);
NCollection_List<std::pair<TopoDS_Shape, TopoDS_Shape>>::Iterator itSub(theShapes);
for (int index = 1; itSub.More(); itSub.Next(), ++index)
{
int anID1 = anIndices.FindIndex(itSub.Value().first);
aSeqOfIDs->SetValue(index, 1, anID1);
int anID2 = anIndices.FindIndex(itSub.Value().second);
aSeqOfIDs->SetValue(index, 2, anID2);
}
return aSeqOfIDs;
}
}
//=======================================================================
//function : GetID
//purpose :
//=======================================================================
const Standard_GUID& GEOMImpl_ConformityDriver::GetID()
{
static Standard_GUID aGUID("B77BABDA-C0A1-4E65-9B1E-7EFC4448077E");
return aGUID;
}
//=======================================================================
//function : GEOMImpl_ConformityDriver
//purpose :
//=======================================================================
GEOMImpl_ConformityDriver::GEOMImpl_ConformityDriver()
{
}
//=======================================================================
//function : Execute
//purpose :
//=======================================================================
Standard_Integer GEOMImpl_ConformityDriver::Execute(Handle(TFunction_Logbook)& log) const
{
if (Label().IsNull()) return 0;
Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
GEOMImpl_IConformity aCI(aFunction);
Standard_Integer aType = aFunction->GetType();
Handle(GEOM_Function) aRefShape = aCI.GetShape();
if (aRefShape.IsNull()) return 0;
TopoDS_Shape aShape = aRefShape->GetValue();
switch (aType)
{
case CONFORMITY_DISTANT_SHAPES:
{
Standard_Integer aType1 = aCI.GetShapeType1();
Standard_Integer aType2 = aCI.GetShapeType2();
NCollection_List<std::pair<TopoDS_Shape, TopoDS_Shape>> aRes;
if (aType1 == -1 && aType2 == -1)
{
aRes = distantShapes(aShape);
}
else if (aType1 == -1)
{
aRes = distantShapes(aShape, (TopAbs_ShapeEnum)aType2);
}
else if (aType2 == -1)
{
aRes = distantShapes(aShape, (TopAbs_ShapeEnum)aType1);
}
else
{
aRes = distantShapes(aShape, (TopAbs_ShapeEnum)aType1, (TopAbs_ShapeEnum)aType2);
}
if (!aRes.IsEmpty())
{
Handle(TColStd_HArray2OfInteger) anArray = ConvertShapesToIndices(aShape, aRes);
aCI.SetListOfShapesIndices(anArray);
}
}
break;
case CONFORMITY_UPDATE_TOL:
{
Standard_Real aTolerance = updateTolerance(aShape);
aFunction->SetReal(CHECKCONFORMITY_RET_TOLERANCE, aTolerance);
}
break;
case CONFORMITY_CHECK_SHAPE:
{
NCollection_List<std::pair<TopoDS_Shape, TopoDS_Shape>> aFailedShape;
Handle(TColStd_HArray1OfInteger) aTypesOfCheck;
checkShape(aShape, aFailedShape, aTypesOfCheck);
Handle(TColStd_HArray2OfInteger) anArray = ConvertShapesToIndices(aShape, aFailedShape);
aFunction->SetIntegerArray(CHECKCONFORMITY_RET_TYPES_CHECKS, aTypesOfCheck);
aCI.SetListOfShapesIndices(anArray);
}
}
return 1;
}
//=======================================================================
//function : distantShapes
//purpose : TODO: Not implemented! Wait for required functionality!
//=======================================================================
NCollection_List<std::pair<TopoDS_Shape, TopoDS_Shape>> GEOMImpl_ConformityDriver::distantShapes(
const TopoDS_Shape& theShape,
const TopAbs_ShapeEnum theShapeType,
const TopAbs_ShapeEnum theSubShapeType,
Standard_Real theTolerance) const
{
// TODO: Not implemented! Wait for required functionality!
return NCollection_List<std::pair<TopoDS_Shape, TopoDS_Shape>>();
}
//=======================================================================
//function : distantShapes
//purpose : TODO: Not implemented! Wait for required functionality!
//=======================================================================
NCollection_List<std::pair<TopoDS_Shape, TopoDS_Shape>> GEOMImpl_ConformityDriver::distantShapes(
const TopoDS_Shape& theShape,
const TopAbs_ShapeEnum theShapeType,
Standard_Real theTolerance) const
{
NCollection_List<std::pair<TopoDS_Shape, TopoDS_Shape>> aDistShapes;
switch (theShapeType)
{
case TopAbs_VERTEX:
aDistShapes.Append(distantShapes(theShape, TopAbs_EDGE, theShapeType, theTolerance));
aDistShapes.Append(distantShapes(theShape, TopAbs_FACE, theShapeType, theTolerance));
break;
case TopAbs_EDGE:
aDistShapes.Append(distantShapes(theShape, theShapeType, TopAbs_VERTEX, theTolerance));
aDistShapes.Append(distantShapes(theShape, TopAbs_FACE, theShapeType, theTolerance));
break;
case TopAbs_FACE:
aDistShapes.Append(distantShapes(theShape, theShapeType, TopAbs_VERTEX, theTolerance));
aDistShapes.Append(distantShapes(theShape, theShapeType, TopAbs_EDGE, theTolerance));
break;
}
return aDistShapes;
}
//=======================================================================
//function : distantShapes
//purpose : TODO: Not implemented! Wait for required functionality!
//=======================================================================
NCollection_List<std::pair<TopoDS_Shape, TopoDS_Shape>> GEOMImpl_ConformityDriver::distantShapes(
const TopoDS_Shape& theShape,
Standard_Real theTolerance) const
{
NCollection_List<std::pair<TopoDS_Shape, TopoDS_Shape>> aDistShapes;
aDistShapes.Append(distantShapes(theShape, TopAbs_EDGE, TopAbs_VERTEX, theTolerance));
aDistShapes.Append(distantShapes(theShape, TopAbs_FACE, TopAbs_VERTEX, theTolerance));
aDistShapes.Append(distantShapes(theShape, TopAbs_FACE, TopAbs_EDGE, theTolerance));
return aDistShapes;
}
void GEOMImpl_ConformityDriver::checkShape(const TopoDS_Shape & theShape,
NCollection_List<std::pair<TopoDS_Shape, TopoDS_Shape>>& theFailedShape,
Handle(TColStd_HArray1OfInteger)& theTypesOfCheck) const
{
BOPAlgo_ArgumentAnalyzer anAnalyzer;
performAnalyze(theShape, anAnalyzer);
const BOPAlgo_ListOfCheckResult& aResult = anAnalyzer.GetCheckResult();
theTypesOfCheck = new TColStd_HArray1OfInteger(1, aResult.Size());
BOPAlgo_ListOfCheckResult::Iterator anIter(aResult);
for (int index = 1; anIter.More(); anIter.Next(), ++index)
{
theTypesOfCheck->SetValue(index, anIter.Value().GetCheckStatus());
std::pair<TopoDS_Shape, TopoDS_Shape> aPair;
aPair.first = anIter.Value().GetFaultyShapes1().First();
if (anIter.Value().GetFaultyShapes1().Size() != 1)
aPair.second = anIter.Value().GetFaultyShapes1().Last();
theFailedShape.Append(aPair);
}
}
//=======================================================================
//function : updateTolerance
//purpose :
//=======================================================================
Standard_Real GEOMImpl_ConformityDriver::updateTolerance(const TopoDS_Shape& theShape) const
{
Standard_Real aTolerance = INFINITY;
TopoDS_Shape aResShape = theShape;
BRepLib::UpdateTolerances(aResShape, Standard_False);
for (const auto& aType : { TopAbs_VERTEX, TopAbs_EDGE, TopAbs_FACE })
{
for (TopExp_Explorer anExp(aResShape, aType); anExp.More(); anExp.Next())
{
Standard_Real aCurTolerance = INFINITY;
switch (aType)
{
case TopAbs_VERTEX:
aCurTolerance = BRep_Tool::Tolerance(TopoDS::Vertex(anExp.Value()));
break;
case TopAbs_EDGE:
aCurTolerance = BRep_Tool::Tolerance(TopoDS::Edge(anExp.Value()));
break;
case TopAbs_FACE:
aCurTolerance = BRep_Tool::Tolerance(TopoDS::Face(anExp.Value()));
break;
}
aTolerance = Min(aTolerance, aCurTolerance);
}
}
TopoDS_Shape aShape = theShape;
GEOMUtils::FixShapeTolerance(aShape, aTolerance, Standard_True);
Standard_Real aResTol = 0.;
for (const auto& aType : { TopAbs_VERTEX, TopAbs_EDGE, TopAbs_FACE })
{
for (TopExp_Explorer anExp(aShape, aType); anExp.More(); anExp.Next())
{
Standard_Real aCurTolerance = INFINITY;
switch (aType)
{
case TopAbs_VERTEX:
aCurTolerance = BRep_Tool::Tolerance(TopoDS::Vertex(anExp.Value()));
break;
case TopAbs_EDGE:
aCurTolerance = BRep_Tool::Tolerance(TopoDS::Edge(anExp.Value()));
break;
case TopAbs_FACE:
aCurTolerance = BRep_Tool::Tolerance(TopoDS::Face(anExp.Value()));
break;
}
aResTol = Max(aResTol, aCurTolerance);
}
}
return aResTol;
}
//=======================================================================
//function : performAnalyze
//purpose :
//=======================================================================
void GEOMImpl_ConformityDriver::performAnalyze(const TopoDS_Shape& theShape,
BOPAlgo_ArgumentAnalyzer& theAnalyzer) const
{
theAnalyzer.SetShape1(theShape);
theAnalyzer.CurveOnSurfaceMode() = Standard_True;
theAnalyzer.SelfInterMode() = Standard_True;
theAnalyzer.SmallEdgeMode() = Standard_True;
theAnalyzer.Perform();
}

View File

@ -0,0 +1,75 @@
// Copyright (C) 2013-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_ConformityDriver_HXX_
#define _GEOMImpl_ConformityDriver_HXX_
#include "GEOM_BaseDriver.hxx"
#include <Standard_Transient.hxx>
#include <TopoDS_Shape.hxx>
#include <BOPAlgo_ArgumentAnalyzer.hxx>
DEFINE_STANDARD_HANDLE(GEOMImpl_ConformityDriver, GEOM_BaseDriver)
class GEOMImpl_ConformityDriver : public GEOM_BaseDriver
{
public:
Standard_EXPORT GEOMImpl_ConformityDriver();
Standard_EXPORT ~GEOMImpl_ConformityDriver() {};
Standard_EXPORT static const Standard_GUID& GetID();
Standard_EXPORT virtual Standard_Integer Execute(Handle(TFunction_Logbook)& log) const;
Standard_EXPORT Standard_Boolean MustExecute(const Handle(TFunction_Logbook)&) const { return Standard_True; }
Standard_EXPORT virtual void Validate(Handle(TFunction_Logbook)&) const {}
private:
Standard_EXPORT NCollection_List<std::pair<TopoDS_Shape, TopoDS_Shape>> distantShapes(const TopoDS_Shape& theShape,
const TopAbs_ShapeEnum theShapeType,
const TopAbs_ShapeEnum theSubShapeType,
Standard_Real theTolerance = -1.) const;
Standard_EXPORT NCollection_List<std::pair<TopoDS_Shape, TopoDS_Shape>> distantShapes(const TopoDS_Shape& theShape,
const TopAbs_ShapeEnum theShapeType,
Standard_Real theTolerance = -1.) const;
Standard_EXPORT NCollection_List<std::pair<TopoDS_Shape, TopoDS_Shape>> distantShapes(const TopoDS_Shape& theShape,
Standard_Real theTolerance = -1.) const;
Standard_EXPORT void checkShape(const TopoDS_Shape& theShape,
NCollection_List<std::pair<TopoDS_Shape, TopoDS_Shape>>& theFailedShape,
Handle(TColStd_HArray1OfInteger)& theTypesOfCheck) const;
Standard_EXPORT Standard_Real updateTolerance(const TopoDS_Shape& theShape) const;
Standard_EXPORT virtual bool GetCreationInformation(std::string& theOperationName,
std::vector<GEOM_Param>& params)
{
return Standard_False;
}
private:
void performAnalyze(const TopoDS_Shape& theShape, BOPAlgo_ArgumentAnalyzer& theAnalyzer) const;
};
#endif // _GEOMImpl_ConformityDriver_HXX_

View File

@ -82,6 +82,7 @@
#include <GEOMImpl_GlueDriver.hxx>
#include <GEOMImpl_MeasureDriver.hxx>
#include <GEOMImpl_FieldDriver.hxx>
#include <GEOMImpl_ConformityDriver.hxx>
//=============================================================================
/*!
@ -161,6 +162,7 @@ GEOMImpl_Gen::GEOMImpl_Gen()
// Measurements
TFunction_DriverTable::Get()->AddDriver(GEOMImpl_MeasureDriver::GetID(), new GEOMImpl_MeasureDriver());
TFunction_DriverTable::Get()->AddDriver(GEOMImpl_ConformityDriver::GetID(), new GEOMImpl_ConformityDriver());
// Field
TFunction_DriverTable::Get()->AddDriver(GEOMImpl_FieldDriver::GetID(), new GEOMImpl_FieldDriver());

View File

@ -0,0 +1,60 @@
// Copyright (C) 2013-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_IConformity.hxx"
//=============================================================================
/*!
* SetListOfShapesIndices
* Input 2D array of indexes converted into 1D array
*/
//=============================================================================
void GEOMImpl_IConformity::SetListOfShapesIndices(const Handle(TColStd_HArray2OfInteger)& theArrayOfIndexes)
{
Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1, theArrayOfIndexes->Size());
for (Standard_Integer aRow = 1; aRow <= theArrayOfIndexes->NbRows(); ++aRow)
{
anArray->SetValue(2 * aRow - 1, theArrayOfIndexes->Value(aRow, 1));
anArray->SetValue(2 * aRow, theArrayOfIndexes->Value(aRow, 2));
}
_func->SetIntegerArray(CHECKCONFORMITY_RET_LIST_OF_INDEXES, anArray);
}
//=============================================================================
/*!
* GetListOfShapesIndices
* Get cached 1D array of indexes and converted into 2D array of indexes
*/
//=============================================================================
Handle(TColStd_HArray2OfInteger) GEOMImpl_IConformity::GetListOfShapesIndices()
{
Handle(TColStd_HArray1OfInteger) anArray = _func->GetIntegerArray(CHECKCONFORMITY_RET_LIST_OF_INDEXES);
Standard_Integer aLength = anArray->Size() / 2;
Handle(TColStd_HArray2OfInteger) aResArray = new TColStd_HArray2OfInteger(1, aLength, 1, 2);
for (Standard_Integer anIndex = 1; anIndex <= aLength; ++anIndex)
{
aResArray->SetValue(anIndex, 1, anArray->Value(2 * anIndex - 1));
aResArray->SetValue(anIndex, 2, anArray->Value(2 * anIndex));
}
return aResArray;
}

View File

@ -0,0 +1,70 @@
// Copyright (C) 2013-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_IConformity_HXX_
#define _GEOMImpl_IConformity_HXX_
#include "GEOM_Function.hxx"
#include <TColStd_HArray2OfInteger.hxx>
#include <TColStd_HArray2OfTransient.hxx>
#define CHECKCONFORMITY_ARG_SHAPE 1
#define CHECKCONFORMITY_ARG_SHAPETYPE_1 2
#define CHECKCONFORMITY_ARG_SHAPETYPE_2 3
#define CHECKCONFORMITY_ARG_TOLERANCE 4
#define CHECKCONFORMITY_RET_TOLERANCE 5
#define CHECKCONFORMITY_RET_ISVALID 6
#define CHECKCONFORMITY_RET_SHAPES_IDS 7
#define CHECKCONFORMITY_RET_TYPES_CHECKS 8
#define CHECKCONFORMITY_RET_LIST_OF_INDEXES 9
#define CHECKCONFORMITY_RET_LIST_SHAPES 10
class GEOMImpl_IConformity
{
public:
GEOMImpl_IConformity(Handle(GEOM_Function) theFunction)
: _func(theFunction)
{
}
void SetShape(Handle(GEOM_Function) theRef)
{
_func->SetReference(CHECKCONFORMITY_ARG_SHAPE, theRef);
}
Handle(GEOM_Function) GetShape()
{
return _func->GetReference(CHECKCONFORMITY_ARG_SHAPE);
}
void SetShapeType1(int theShapeType) { _func->SetInteger(CHECKCONFORMITY_ARG_SHAPETYPE_1, theShapeType); }
Standard_Integer GetShapeType1() { return _func->GetInteger(CHECKCONFORMITY_ARG_SHAPETYPE_1); }
void SetShapeType2(int theShapeType) { _func->SetInteger(CHECKCONFORMITY_ARG_SHAPETYPE_2, theShapeType); }
Standard_Integer GetShapeType2() { return _func->GetInteger(CHECKCONFORMITY_ARG_SHAPETYPE_2); }
void SetTolerance(double theTolerance) { _func->SetReal(CHECKCONFORMITY_ARG_TOLERANCE, theTolerance); }
Standard_Real GetTolerance() { return _func->GetReal(CHECKCONFORMITY_ARG_TOLERANCE); }
void SetListOfShapesIndices(const Handle(TColStd_HArray2OfInteger)& theArrayOfIndexes);
Handle(TColStd_HArray2OfInteger) GetListOfShapesIndices();
private:
Handle(GEOM_Function) _func;
};
#endif // _GEOMImpl_IConformity_HXX_

View File

@ -25,6 +25,9 @@
#include <GEOMImpl_MeasureDriver.hxx>
#include <GEOMImpl_Types.hxx>
#include <GEOMImpl_IConformity.hxx>
#include <GEOMImpl_ConformityDriver.hxx>
#include <GEOMUtils.hxx>
#include <GEOMAlgo_AlgoTools.hxx>
@ -2658,6 +2661,351 @@ Standard_Real GEOMImpl_IMeasureOperations::MinSurfaceCurvatureByPoint
return getSurfaceCurvatures(aSurf, UV.X(), UV.Y(), false);
}
//=============================================================================
/*!
* selfIntersected2D
* Find all self-intersected 2D curves.
* \param theChecks list of failed checks, contains type of check and failed shapes
*/
//=============================================================================
std::list<GEOMImpl_IMeasureOperations::FailedShapes> GEOMImpl_IMeasureOperations::selfIntersected2D(
std::list<FailedChecks>& theChecks)
{
SetErrorCode(KO);
MESSAGE("GEOMImpl_IMeasureOperations::selfIntersected2D");
std::list<GEOMImpl_IMeasureOperations::FailedShapes> aSelfInters2D;
Handle(GEOM_Object) aConformity = GetEngine()->AddObject(GEOM_CHECKCONFORMITY);
Handle(GEOM_Function) aFunction = aConformity->AddFunction(GEOMImpl_ConformityDriver::GetID(), CONFORMITY_SELFINTERSECTED);
if (aFunction.IsNull()) return aSelfInters2D;
//Check if the function is set correctly
if (aFunction->GetDriverGUID() != GEOMImpl_ConformityDriver::GetID()) return aSelfInters2D;
GEOMImpl_IConformity aCI(aFunction);
try
{
OCC_CATCH_SIGNALS;
for (std::list<FailedChecks>::iterator anIter(theChecks.begin());
anIter != theChecks.end(); ++anIter)
{
if (anIter->TypeOfCheck == BOPAlgo_CheckStatus::BOPAlgo_InvalidCurveOnSurface)
aSelfInters2D.push_back(anIter->FailedShapes);
}
}
catch (Standard_Failure& aFail)
{
SetErrorCode(aFail.GetMessageString());
return aSelfInters2D;
}
SetErrorCode(OK);
return aSelfInters2D;
}
//=============================================================================
/*!
* interferingSubshapes
* Find pairs of interfering sub-shapes, by default all pairs of interfering shapes are returned.
* \param theChecks list of failed checks, contains type of check and failed shapes
* \param theShapeType1 Type of shape.
* \param theShapeType2 Type of shape.
*/
//=============================================================================
std::list<GEOMImpl_IMeasureOperations::FailedShapes> GEOMImpl_IMeasureOperations::interferingSubshapes(
std::list<FailedChecks>& theChecks,
const int theShapeType1,
const int theShapeType2)
{
SetErrorCode(KO);
MESSAGE("GEOMImpl_IMeasureOperations::interferingSubshapes");
std::list < GEOMImpl_IMeasureOperations::FailedShapes> anInterfer;
try
{
OCC_CATCH_SIGNALS;
for (std::list<FailedChecks>::iterator anIter(theChecks.begin());
anIter != theChecks.end(); ++anIter)
{
if (anIter->TypeOfCheck == BOPAlgo_CheckStatus::BOPAlgo_SelfIntersect &&
checkTypes(anIter->FailedShapes, theShapeType1, theShapeType2))
anInterfer.push_back(anIter->FailedShapes);
}
}
catch (Standard_Failure& aFail)
{
SetErrorCode(aFail.GetMessageString());
return anInterfer;
}
SetErrorCode(OK);
return anInterfer;
}
//=============================================================================
/*!
* smallEdges
* Find edges, which are fully covered by tolerances of vertices.
* \param theChecks list of failed checks, contains type of check and failed shapes
*/
//=============================================================================
Handle(TColStd_HSequenceOfTransient) GEOMImpl_IMeasureOperations::smallEdges(std::list<FailedChecks>& theChecks)
{
SetErrorCode(KO);
MESSAGE("GEOMImpl_IMeasureOperations::smallEdges");
Handle(TColStd_HSequenceOfTransient) aSmallEdges = new TColStd_HSequenceOfTransient;
try
{
OCC_CATCH_SIGNALS;
for (std::list<FailedChecks>::iterator anIter(theChecks.begin());
anIter != theChecks.end(); ++anIter)
{
if (anIter->TypeOfCheck == BOPAlgo_CheckStatus::BOPAlgo_TooSmallEdge)
aSmallEdges->Append(anIter->FailedShapes.first);
}
}
catch (Standard_Failure& aFail)
{
SetErrorCode(aFail.GetMessageString());
return NULL;
}
SetErrorCode(OK);
return aSmallEdges;
}
//=============================================================================
/*!
* distantShapes
* find remote objects (sub-shape on a shape).
* \param theShape Shape for check.
* \param theShapeType Type of shape.
* \param theSubShapeType Type of sub-shape.
* \param theTolerance tolerance.
*/
//=============================================================================
std::list<GEOMImpl_IMeasureOperations::FailedShapes> GEOMImpl_IMeasureOperations::distantShapes(
Handle(GEOM_Object) theShape,
const int theShapeType,
const int theSubShapeType,
double theTolerance)
{
SetErrorCode(KO);
MESSAGE("GEOMImpl_IMeasureOperations::distantShapes");
std::list<GEOMImpl_IMeasureOperations::FailedShapes> aDistantS;
Handle(GEOM_Object) aConformity = GetEngine()->AddObject(GEOM_CHECKCONFORMITY);
Handle(GEOM_Function) aFunction = aConformity->AddFunction(GEOMImpl_ConformityDriver::GetID(), CONFORMITY_DISTANT_SHAPES);
if (aFunction.IsNull()) return aDistantS;
//Check if the function is set correctly
if (aFunction->GetDriverGUID() != GEOMImpl_ConformityDriver::GetID()) return aDistantS;
GEOMImpl_IConformity aCI(aFunction);
Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
if (aRefShape.IsNull()) return aDistantS;
aCI.SetShape(aRefShape);
aCI.SetShapeType1(theShapeType);
aCI.SetShapeType2(theSubShapeType);
aCI.SetTolerance(theTolerance);
try
{
OCC_CATCH_SIGNALS;
if (!GetSolver()->ComputeFunction(aFunction))
{
SetErrorCode("Failed: distantShape");
return aDistantS;
}
TopTools_IndexedMapOfShape anIndices;
TopExp::MapShapes(theShape->GetValue(), anIndices);
Handle(TColStd_HArray1OfInteger) aRes = aFunction->GetIntegerArray(CHECKCONFORMITY_RET_SHAPES_IDS);
if (aRes.IsNull())
return aDistantS;
for (Standard_Integer anIndex = 1; anIndex <= aRes->Size() / 2; ++anIndex)
{
std::pair<Handle(GEOM_Object), Handle(GEOM_Object)> aPair;
Handle(TColStd_HArray1OfInteger) anArray;
anArray = new TColStd_HArray1OfInteger(1, 1);
anArray->SetValue(1, aRes->Value(2 * anIndex - 1));
Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
if (!anObj.IsNull())
aPair.first = anObj;
anArray = new TColStd_HArray1OfInteger(1, 1);
anArray->SetValue(1, aRes->Value(2 * anIndex));
anObj = GetEngine()->AddSubShape(theShape, anArray);
if (!anObj.IsNull())
aPair.second = anObj;
aDistantS.push_back(aPair);
}
}
catch (Standard_Failure& aFail)
{
SetErrorCode(aFail.GetMessageString());
return aDistantS;
}
SetErrorCode(OK);
return aDistantS;
}
//=============================================================================
/*!
* checkConformityShape
* Perform analyse of shape and find imperfections in the shape.
* \param theShape Shape for analyse.
*/
//=============================================================================
void GEOMImpl_IMeasureOperations::checkConformityShape(Handle(GEOM_Object) theShape, std::list<FailedChecks>& theChecks)
{
SetErrorCode(KO);
MESSAGE("GEOMImpl_IMeasureOperations::checkShape");
Handle(GEOM_Object) aConformity = GetEngine()->AddObject(GEOM_CHECKCONFORMITY);
Handle(GEOM_Function) aFunction = aConformity->AddFunction(GEOMImpl_ConformityDriver::GetID(), CONFORMITY_CHECK_SHAPE);
if (aFunction.IsNull()) return;
//Check if the function is set correctly
if (aFunction->GetDriverGUID() != GEOMImpl_ConformityDriver::GetID()) return;
GEOMImpl_IConformity aCI(aFunction);
Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
if (aRefShape.IsNull()) return;
aCI.SetShape(aRefShape);
try
{
OCC_CATCH_SIGNALS;
if (!GetSolver()->ComputeFunction(aFunction))
{
SetErrorCode("Failed: checkShape");
return;
}
Handle(TColStd_HArray1OfInteger) aTypesChecks = aFunction->GetIntegerArray(CHECKCONFORMITY_RET_TYPES_CHECKS);
Handle(TColStd_HArray2OfInteger) aRes = aCI.GetListOfShapesIndices();
if (aRes.IsNull())
return;
for (Standard_Integer anIndex = 1; anIndex <= aRes->NbRows(); ++anIndex)
{
std::pair<Handle(GEOM_Object), Handle(GEOM_Object)> aPair;
Handle(TColStd_HArray1OfInteger) anArray;
anArray = new TColStd_HArray1OfInteger(1, 1);
anArray->SetValue(1, aRes->Value(anIndex, 1));
Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
if (!anObj.IsNull())
aPair.first = anObj;
anArray = new TColStd_HArray1OfInteger(1, 1);
anArray->SetValue(1, aRes->Value(anIndex, 2));
anObj = GetEngine()->AddSubShape(theShape, anArray);
if (!anObj.IsNull())
aPair.second = anObj;
theChecks.push_back({ aTypesChecks->Value(anIndex), aPair });
}
}
catch (Standard_Failure& aFail)
{
SetErrorCode(aFail.GetMessageString());
return;
}
SetErrorCode(OK);
return;
}
//=============================================================================
/*!
* updateTolerance
* Compute possible tolerance for the shape, minimize tolerance of shape as well
* as tolerance of sub-shapes as much as possible
* \param theShape Shape for compute tolerance.
*/
//=============================================================================
double GEOMImpl_IMeasureOperations::updateTolerance(Handle(GEOM_Object) theShape)
{
SetErrorCode(KO);
MESSAGE("GEOMImpl_IMeasureOperations::updateTolerance");
double aResTol = -1;
Handle(GEOM_Object) aConformity = GetEngine()->AddObject(GEOM_CHECKCONFORMITY);
Handle(GEOM_Function) aFunction = aConformity->AddFunction(GEOMImpl_ConformityDriver::GetID(), CONFORMITY_UPDATE_TOL);
if (aFunction.IsNull()) return aResTol;
//Check if the function is set correctly
if (aFunction->GetDriverGUID() != GEOMImpl_ConformityDriver::GetID()) return aResTol;
GEOMImpl_IConformity aCI(aFunction);
Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
if (aRefShape.IsNull()) return aResTol;
aCI.SetShape(aRefShape);
try
{
OCC_CATCH_SIGNALS;
if (!GetSolver()->ComputeFunction(aFunction))
{
SetErrorCode("Failed: updateTolerance");
return aResTol;
}
aResTol = aFunction->GetReal(CHECKCONFORMITY_RET_TOLERANCE);
}
catch (Standard_Failure& aFail)
{
SetErrorCode(aFail.GetMessageString());
return aResTol;
}
SetErrorCode(OK);
return aResTol;
}
//=======================================================================
//function : checkTypes
//purpose :
//=======================================================================
bool GEOMImpl_IMeasureOperations::checkTypes(const FailedShapes& theShapes,
const int theShapeType1,
const int theShapeType2)
{
TopAbs_ShapeEnum aShapeType1, aShapeType2;
if (!theShapes.first.IsNull())
aShapeType1 = theShapes.first->GetValue().ShapeType();
if (!theShapes.second.IsNull())
aShapeType2 = theShapes.second->GetValue().ShapeType();
if (theShapeType1 == -1 && theShapeType2 == -1)
{
return true;
}
else if (theShapeType1 == -1)
{
return aShapeType1 == theShapeType2 || aShapeType2 == theShapeType2;
}
else if (theShapeType2 == -1)
{
return aShapeType1 == theShapeType1 || aShapeType2 == theShapeType1;
}
else
{
return aShapeType1 == theShapeType1 && aShapeType2 == theShapeType2 ||
aShapeType1 == theShapeType2 && aShapeType2 == theShapeType1;
}
}
//=======================================================================
//function : FillErrorsSub
//purpose : Fill the errors list of subshapes on shape.

View File

@ -215,9 +215,32 @@ class GEOMImpl_IMeasureOperations : public GEOM_IOperations {
Standard_Real& theVParam);
Standard_EXPORT Standard_Real MinSurfaceCurvatureByPoint (Handle(GEOM_Object) theSurf,
Handle(GEOM_Object) thePoint);
typedef std::pair< Handle(GEOM_Object), Handle(GEOM_Object)> FailedShapes;
struct FailedChecks
{
Standard_Integer TypeOfCheck;
FailedShapes FailedShapes;
};
Standard_EXPORT std::list<FailedShapes> selfIntersected2D(std::list<FailedChecks>& theChecks);
Standard_EXPORT std::list<FailedShapes> interferingSubshapes(std::list<FailedChecks>& theChecks,
const int theShapeType1,
const int theShapeType2);
Standard_EXPORT Handle(TColStd_HSequenceOfTransient) smallEdges(std::list<FailedChecks>& theChecks);
Standard_EXPORT std::list<FailedShapes> distantShapes(Handle(GEOM_Object) theShape,
const int theShapeType,
const int theSubShapeType,
double theTolerance);
Standard_EXPORT void checkConformityShape(Handle(GEOM_Object) theShape, std::list<FailedChecks>& theChecks);
Standard_EXPORT double updateTolerance(Handle(GEOM_Object) theShape);
private:
bool checkTypes(const FailedShapes& theShapes,
const int theShapeType1,
const int theShapeType2);
void FillErrorsSub
(const BRepCheck_Analyzer &theAna,
const TopoDS_Shape &theShape,

View File

@ -121,6 +121,8 @@
#define GEOM_EXTRACTION 58
#define GEOM_CHECKCONFORMITY 59
//GEOM_Function types
#define COPY_WITH_REF 1
@ -391,6 +393,15 @@
#define TD_GET_IN_PLACE_OLD 2
#define TD_GET_IN_PLACE_BY_HISTORY 3
// Conformity operations
#define CONFORMITY_IS_VALID 2
#define CONFORMITY_SELFINTERSECTED 3
#define CONFORMITY_INTERFERENCE 4
#define CONFORMITY_SMALL_EDGES 5
#define CONFORMITY_DISTANT_SHAPES 6
#define CONFORMITY_UPDATE_TOL 7
#define CONFORMITY_CHECK_SHAPE 8
// Plugins specified constants
#define PLUGIN_NAME "Plugin Name"

View File

@ -1188,3 +1188,203 @@ CORBA::Double GEOM_IMeasureOperations_i::MinSurfaceCurvatureByPoint
return GetOperations()->MinSurfaceCurvatureByPoint(aShape,aPoint);
}
//=============================================================================
/*!
* selfIntersected2D
* Find all self-intersected 2D curves.
* \param theShape Shape for check.
*/
//=============================================================================
GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape* GEOM_IMeasureOperations_i::selfIntersected2D(
const GEOM::GEOM_IMeasureOperations::CheckResults& theResuts)
{
GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape_var aSeq =
new GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape;
// Perform patch face operation
std::list<GEOMImpl_IMeasureOperations::FailedChecks> aResults;
ConvertToList(theResuts, aResults);
std::list<GEOMImpl_IMeasureOperations::FailedShapes> aSelfInters = GetOperations()->selfIntersected2D(aResults);
if (!GetOperations()->IsDone() || aSelfInters.empty())
return aSeq._retn();
Standard_Integer aLength = aSelfInters.size();
aSeq->length(aLength);
std::list<GEOMImpl_IMeasureOperations::FailedShapes>::iterator anIter(aSelfInters.begin());
for (Standard_Integer i = 0; i < aLength; i++, ++anIter)
{
aSeq[i].first = GetObject(Handle(::GEOM_Object)::DownCast((*anIter).first));
aSeq[i].second = GetObject(Handle(::GEOM_Object)::DownCast((*anIter).second));
}
return aSeq._retn();
}
//=============================================================================
/*!
* interferingSubshapes
* Find pairs of interfering sub-shapes, by default all pairs of interfering shapes are returned.
* \param theShape Shape for check.
* \param theShapeType1 Type of shape.
* \param theShapeType2 Type of shape.
*/
//=============================================================================
GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape* GEOM_IMeasureOperations_i::interferingSubshapes(
const GEOM::GEOM_IMeasureOperations::CheckResults& theResuts,
const CORBA::Long theShapeType1,
const CORBA::Long theShapeType2)
{
GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape_var aSeq =
new GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape;
// Perform patch face operation
std::list<GEOMImpl_IMeasureOperations::FailedChecks> aResults;
ConvertToList(theResuts, aResults);
std::list<GEOMImpl_IMeasureOperations::FailedShapes> aSelfInterf =
GetOperations()->interferingSubshapes(aResults, theShapeType1, theShapeType2);
if (!GetOperations()->IsDone() || aSelfInterf.empty())
return aSeq._retn();
Standard_Integer aLength = aSelfInterf.size();
aSeq->length(aLength);
std::list<GEOMImpl_IMeasureOperations::FailedShapes>::iterator anIter(aSelfInterf.begin());
for (Standard_Integer i = 0; i < aLength; i++, ++anIter)
{
aSeq[i].first = GetObject(Handle(::GEOM_Object)::DownCast((*anIter).first));
aSeq[i].second = GetObject(Handle(::GEOM_Object)::DownCast((*anIter).second));
}
return aSeq._retn();
}
//=============================================================================
/*!
* smallEdges
* Find edges, which are fully covered by tolerances of vertices.
* \param theShape Shape for check.
*/
//=============================================================================
GEOM::ListOfGO* GEOM_IMeasureOperations_i::smallEdges(const GEOM::GEOM_IMeasureOperations::CheckResults& theResuts)
{
GEOM::ListOfGO_var aSeq = new GEOM::ListOfGO;
std::list<GEOMImpl_IMeasureOperations::FailedChecks> aResults;
ConvertToList(theResuts, aResults);
//Get the reference shape
Handle(TColStd_HSequenceOfTransient) aSmallEdges = GetOperations()->smallEdges(aResults);
if (!GetOperations()->IsDone() || aSmallEdges.IsNull())
return aSeq._retn();
Standard_Integer aLength = aSmallEdges->Length();
aSeq->length(aLength);
for (Standard_Integer i = 1; i <= aLength; i++)
aSeq[i - 1] = GetObject(Handle(::GEOM_Object)::DownCast(aSmallEdges->Value(i)));
return aSeq._retn();
}
//=============================================================================
/*!
* distantShapes
* find remote objects (sub-shape on a shape).
* \param theShape Shape for check.
* \param theShapeType Type of shape.
* \param theSubShapeType Type of sub-shape.
* \param theTolerance tolerance.
*/
//=============================================================================
GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape* GEOM_IMeasureOperations_i::distantShapes(
GEOM::GEOM_Object_ptr theShape,
const CORBA::Long theShapeType,
const CORBA::Long theSubShapeType,
const CORBA::Double theTolerance)
{
GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape_var aSeq =
new GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape;
//Get the reference shape
Handle(::GEOM_Object) aShapeRef = GetObjectImpl(theShape);
if (aShapeRef.IsNull()) return aSeq._retn();
// Perform patch face operation
std::list<GEOMImpl_IMeasureOperations::FailedShapes> aDistantS =
GetOperations()->distantShapes(aShapeRef, theShapeType, theSubShapeType, theTolerance);
if (!GetOperations()->IsDone() || aDistantS.empty())
return aSeq._retn();
Standard_Integer aLength = aDistantS.size();
aSeq->length(aLength);
std::list<GEOMImpl_IMeasureOperations::FailedShapes>::iterator anIter(aDistantS.begin());
for (Standard_Integer i = 0; i < aLength; i++, ++anIter)
{
aSeq[i].first = GetObject(Handle(::GEOM_Object)::DownCast((*anIter).first));
aSeq[i].second = GetObject(Handle(::GEOM_Object)::DownCast((*anIter).second));
}
return aSeq._retn();
}
//=============================================================================
/*!
* checkShape
*
*/
//=============================================================================
GEOM::GEOM_IMeasureOperations::CheckResults* GEOM_IMeasureOperations_i::checkConformityShape(
GEOM::GEOM_Object_ptr theShape)
{
GEOM::GEOM_IMeasureOperations::CheckResults_var aRes = new GEOM::GEOM_IMeasureOperations::CheckResults;
//Get the reference shape
Handle(::GEOM_Object) aShapeRef = GetObjectImpl(theShape);
if (aShapeRef.IsNull()) return false;
std::list<GEOMImpl_IMeasureOperations::FailedChecks> aChecks;
GetOperations()->checkConformityShape(aShapeRef, aChecks);
Standard_Integer aLength = aChecks.size();
aRes->length(aLength);
std::list<GEOMImpl_IMeasureOperations::FailedChecks>::const_iterator anIntIt = aChecks.cbegin();
for (Standard_Integer i = 0; i < aLength; i++, ++anIntIt)
{
aRes[i].type = (*anIntIt).TypeOfCheck;
aRes[i].failedShapes.first = GetObject(Handle(::GEOM_Object)::DownCast((*anIntIt).FailedShapes.first));
aRes[i].failedShapes.second = GetObject(Handle(::GEOM_Object)::DownCast((*anIntIt).FailedShapes.second));
}
return aRes._retn();
}
//=============================================================================
/*!
* updateTolerance
* Compute possible tolerance for the shape, minimize tolerance of shape as well
* as tolerance of sub-shapes as much as possible
* \param theShape Shape for check.
*/
//=============================================================================
CORBA::Double GEOM_IMeasureOperations_i::updateTolerance(GEOM::GEOM_Object_ptr theShape)
{
//Get the reference shape
Handle(::GEOM_Object) aShapeRef = GetObjectImpl(theShape);
if (aShapeRef.IsNull()) return false;
return GetOperations()->updateTolerance(aShapeRef);
}
void GEOM_IMeasureOperations_i::ConvertToList(const GEOM::GEOM_IMeasureOperations::CheckResults& theResuts,
std::list<GEOMImpl_IMeasureOperations::FailedChecks>& theListOfResults)
{
for (Standard_Integer i = 0; i < theResuts.length(); ++i)
{
GEOMImpl_IMeasureOperations::FailedChecks aCheck;
aCheck.TypeOfCheck = theResuts[i].type;
aCheck.FailedShapes.first = GetObjectImpl(theResuts[i].failedShapes.first);
aCheck.FailedShapes.second = GetObjectImpl(theResuts[i].failedShapes.second);
theListOfResults.push_back(aCheck);
}
}

View File

@ -164,6 +164,30 @@ class GEOM_I_EXPORT GEOM_IMeasureOperations_i :
CORBA::Double MinSurfaceCurvatureByPoint (GEOM::GEOM_Object_ptr theSurf,
GEOM::GEOM_Object_ptr thePoint);
// Methods for class CheckConformity
GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape* selfIntersected2D(
const GEOM::GEOM_IMeasureOperations::CheckResults& theResuts);
GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape* interferingSubshapes(
const GEOM::GEOM_IMeasureOperations::CheckResults& theResuts,
const CORBA::Long theShapeType1,
const CORBA::Long theShapeType2);
GEOM::ListOfGO* smallEdges(const GEOM::GEOM_IMeasureOperations::CheckResults& theResuts);
GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape* distantShapes(GEOM::GEOM_Object_ptr theShape,
const CORBA::Long theShapeType,
const CORBA::Long theSubShapeType,
const CORBA::Double theTolerance);
GEOM::GEOM_IMeasureOperations::CheckResults* checkConformityShape(GEOM::GEOM_Object_ptr theShape);
CORBA::Double updateTolerance(GEOM::GEOM_Object_ptr theShape);
private:
void ConvertToList(const GEOM::GEOM_IMeasureOperations::CheckResults& theResuts,
std::list <GEOMImpl_IMeasureOperations::FailedChecks>& theListOfResults);
::GEOMImpl_IMeasureOperations* GetOperations()
{ return (::GEOMImpl_IMeasureOperations*)GetImpl(); }
};

View File

@ -71,6 +71,7 @@ SET(_other_SCRIPTS
SET(_python_SCRIPTS
geomBuilder.py
gsketcher.py
CheckConformity.py
)
# Advanced scripts

View File

@ -0,0 +1,333 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2014-2022 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
#
# Author : Alexey SOZINOV, Open CASCADE S.A.S.
## @defgroup check_conformity CheckConformity - Wrapper to find imperfections in the shape
# @{
# @details
# This tool provides the user with a simple python API
# to analyze, available shape for Boolean Operations or not.
# Also tool provide advanced output to indicate imperfections in the input shape.
# @n Example:
# @code
# import GEOM
# from salome.geom import geomBuilder
# from salome.geom.CheckConformity import CheckConformity
#
# 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)
# Vertex_1 = geompy.MakeVertex(-30, -70, 0)
# Vertex_2 = geompy.MakeVertex(-30, 50, 0)
# Line_1 = geompy.MakeLineTwoPnt(Vertex_2, Vertex_1)
# Vertex_3 = geompy.MakeVertex(0, -50, 0)
# Vertex_4 = geompy.MakeVertex(-40, -10, 0)
# Vertex_5 = geompy.MakeVertex(0, 40, 0)
# Arc_1 = geompy.MakeArc(Vertex_5, Vertex_4, Vertex_3)
# Vertex_6 = geompy.MakeVertex(10, -50, 4)
# Vertex_7 = geompy.MakeVertex(10, -50, 10)
# Vertex_8 = geompy.MakeVertex(10, 40, 10)
# Arc_1_vertex_3 = geompy.GetSubShape(Arc_1, [3])
# Line_2 = geompy.MakeLineTwoPnt(Arc_1_vertex_3, Vertex_6)
# Line_3 = geompy.MakeLineTwoPnt(Vertex_6, Vertex_7)
# Line_4 = geompy.MakeLineTwoPnt(Vertex_7, Vertex_8)
# Vertex_9 = geompy.MakeVertex(15, 40, 10)
# Vertex_10 = geompy.MakeVertex(17, 0, 6)
# Vertex_11 = geompy.MakeVertex(17, 0, 3)
# Line_5 = geompy.MakeLineTwoPnt(Vertex_8, Vertex_9)
# Line_6 = geompy.MakeLineTwoPnt(Vertex_9, Vertex_10)
# Line_7 = geompy.MakeLineTwoPnt(Vertex_10, Vertex_11)
# Arc_1_vertex_2 = geompy.GetSubShape(Arc_1, [2])
# Line_8 = geompy.MakeLineTwoPnt(Vertex_11, Arc_1_vertex_2)
# Wire_1 = geompy.MakeWire([Arc_1, Line_2, Line_3, Line_4, Line_5, Line_6, Line_7, Line_8], 1e-07)
# Wire_2 = geompy.MakeWire([Line_1], 1e-07)
# Compound_1 = geompy.MakeCompound([Wire_1, Wire_2])
#
# # Create class CheckConformity for check shape
# cc = CheckConformity(Compound_1, geompy)
# valid = cc.isValid()
# dist = cc.distantShapes()
# small = cc.smallEdges()
# interfer = cc.interferingSubshapes()
# intersect = cc.selfIntersected2D()
#
# geompy.addToStudy( O, 'O' )
# geompy.addToStudy( OX, 'OX' )
# geompy.addToStudy( OY, 'OY' )
# geompy.addToStudy( OZ, 'OZ' )
# geompy.addToStudy( Vertex_1, 'Vertex_1' )
# geompy.addToStudy( Vertex_2, 'Vertex_2' )
# geompy.addToStudy( Line_1, 'Line_1' )
# geompy.addToStudy( Vertex_3, 'Vertex_3' )
# geompy.addToStudy( Vertex_4, 'Vertex_4' )
# geompy.addToStudy( Vertex_5, 'Vertex_5' )
# geompy.addToStudy( Arc_1, 'Arc_1' )
# geompy.addToStudy( Vertex_6, 'Vertex_6' )
# geompy.addToStudy( Vertex_7, 'Vertex_7' )
# geompy.addToStudy( Vertex_8, 'Vertex_8' )
# geompy.addToStudyInFather( Arc_1, Arc_1_vertex_3, 'Arc_1:vertex_3' )
# geompy.addToStudy( Line_2, 'Line_2' )
# geompy.addToStudy( Line_3, 'Line_3' )
# geompy.addToStudy( Line_4, 'Line_4' )
# geompy.addToStudy( Vertex_9, 'Vertex_9' )
# geompy.addToStudy( Vertex_10, 'Vertex_10' )
# geompy.addToStudy( Vertex_11, 'Vertex_11' )
# geompy.addToStudy( Line_5, 'Line_5' )
# geompy.addToStudy( Line_6, 'Line_6' )
# geompy.addToStudy( Line_7, 'Line_7' )
# geompy.addToStudyInFather( Arc_1, Arc_1_vertex_2, 'Arc_1:vertex_2' )
# geompy.addToStudy( Line_8, 'Line_8' )
# geompy.addToStudy( Wire_1, 'Wire_1' )
# geompy.addToStudy( Wire_2, 'Wire_2' )
# geompy.addToStudy( Compound_1, 'Compound_1' )
#
# salome.sg.updateObjBrowser()
#
# @endcode
# @n Additional examples can be found as unit tests in the source code.
# @}
try:
import salome
salome.salome_init()
from salome import *
except:
pass
import GEOM
from salome.geom import geomBuilder
geompy = geomBuilder.New()
## An interface to find imperfections in the shape.
# Use geompy.CheckConformity(shape) method to obtain an instance of this class
#
# @ref tui_check_conformity_page "Example"
# @ingroup check_conformity
class CheckConformity:
"""
Check Conformity interface
Example of usage:
cc = CheckConformity(Lot4_twistedFace_brep_1, geompy)
valid = cc.isValid()
dist = cc.distantShapes(geompy.ShapeType["EDGE"], geompy.ShapeType["VERTEX"]) !!NOT implemented!
small = cc.smallEdges()
interfer = cc.interferingSubshapes()
interferEV = cc.interferingSubshapes(geompy.ShapeType["EDGE"], geompy.ShapeType["VERTEX"])
interferVV = cc.interferingSubshapes(geompy.ShapeType["VERTEX], geompy.ShapeType["VERTEX"])
intersect = cc.selfIntersected2D()
"""
def __init__(self, shape, geompy):
self.geompyD = geompy
self.myShape = shape
self.myIsChecked = False;
self.myResults = []
## Perform analyse of shape.
#
# @return New List, which contains pair: type of check and single of pair failed sub-shapes.
def __checkShape(self):
"""
Perform analyse of shape.
Returns:
New List, which contains pair: type of check and single of pair failed sub-shapes.
"""
anOp = self.geompyD.GetIMeasureOperations()
self.myIsChecked = True
self.myResults = anOp.checkConformityShape(self.myShape)
## Check whether the shape is applicable for Boolean Operations.
#
# @return Boolean value True if shape is applicable for Boolean Operations, otherwise - False
def isValid(self):
"""
check whether the shape is applicable for Boolean Operations.
Returns:
Boolean value True if shape is applicable for Boolean Operations, otherwise - False.
Example of usage:
Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200)
cc = CheckConformity(Box_1, geompy)
isValid = cc.isValid()
"""
if not self.myIsChecked:
self.__checkShape()
anOp = self.geompyD.GetIMeasureOperations()
return len(self.myResults) == 0
## Find all self-intersected 2D curves.
#
# @return New List, of pair sub-shape, which has self-intersected in 2D
def selfIntersected2D(self):
"""
Find all self-intersected 2D curves.
Returns:
New List, of pair sub-shape, which has self-intersected in 2D/
Example of usage:
Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200)
cc = CheckConformity(Box_1, geompy)
selfIntersected2D = cc.selfIntersected2D()
"""
if not self.myIsChecked:
self.__checkShape()
anOp = self.geompyD.GetIMeasureOperations()
return anOp.selfIntersected2D(self.myResults)
## Find pairs of interfering sub-shapes:
# - vertices touched by tolerance;
# - vertex touching an edge in the inner point;
# - vertex lying on the inner point of a face;
# - edges intersecting by inner points;
# - edge touching/intersecting face in the inner point;
# - faces intersection by inner point
#
# Types of interfering shapes could be specified,
# by default all pairs of interfering shapes are returned.
#
# @param shapeType1 first type of shape
# @param shapeType2 second type of shape
#
# @return New List, of pairs of interfering shapes with given types (if they was specified)
def interferingSubshapes(self, shapeType1 = geompy.ShapeType["AUTO"], shapeType2 = geompy.ShapeType["AUTO"]):
"""
Find pairs of interfering sub-shapes:
- vertices touched by tolerance
- vertex touching an edge in the inner point
- vertex lying on the inner point of a face
- edges intersecting by inner points
- edge touching/intersecting face in the inner point
- faces intersection by inner point
Types of interfering shapes could be specified, by default all pairs of
interfering shapes are returned.
Parameters:
shapeType1 first type of shape
shapeType2 second type of shape
Returns:
New List, of pairs of interfering shapes with given types (if they was specified)
Example of usage:
Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200)
cc = CheckConformity(Box_1, geompy)
interferingSubshapes = cc.interferingSubshapes()
interferingSubshapesVV = cc.interferingSubshapes(geompy.ShapeType["VERTEX"], geompy.ShapeType["VERTEX"])
"""
if not self.myIsChecked:
self.__checkShape()
anOp = self.geompyD.GetIMeasureOperations()
return anOp.interferingSubshapes(self.myResults, shapeType1, shapeType2)
## Find edges, which are fully covered by tolerances of vertices.
#
# @return New List of edges, which are fully covered by tolerances of vertices
def smallEdges(self):
"""
Find edges, which are fully covered by tolerances of vertices.
Returns:
New List of edges, which are fully covered by tolerances of vertices.
Example of usage:
Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200)
cc = CheckConformity(Box_1, geompy)
smallEdges = cc.smallEdges()
"""
if not self.myIsChecked:
self.__checkShape()
anOp = self.geompyD.GetIMeasureOperations()
return anOp.smallEdges(self.myResults)
## Find remote objects (sub-shape on a shape):
# - vertex far from edge;
# - vertex far from face;
# - edge far from face
#
# Sub-shape which are lying far from its parent shape more than the given tolerance.
#
# @param shapeType type of shape
# @param subShapeType type of sub-shape
# @param tolerance available tolerance, by default used tolerance of sub-shape.
#
# @return New List, of pair of sub-shape with given types,
# that lying far from its parent shape more than the given tolerance.
def distantShapes(self, shapeType = geompy.ShapeType["AUTO"], subShapeType = geompy.ShapeType["AUTO"], tolerance = -1.0):
"""
Find remote objects (sub-shape on a shape):
- vertex far from edge;
- vertex far from face;
- edge far from face
Sub-shape which are lying far from its parent shape more than the given tolerance.
Parameters:
shapeType type of shape
subShapeType type of sub-shape
tolerance available tolerance, by default used tolerance of sub-shape.
Returns:
New List, of pair of sub-shape with given types,
that lying far from its parent shape more than the given tolerance
Example of usage:
Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200)
cc = CheckConformity(Box_1, geompy)
distantShapes = cc.distantShapes(geompy.ShapeType["EDGE"], geompy.ShapeType["VERTEX"])
"""
anOp = self.geompyD.GetIMeasureOperations()
return anOp.distantShapes(self.myShape, shapeType, subShapeType, tolerance)
## Compute possible tolerance for the shape,
# minimize tolerance of shape as well as tolerance of sub-shapes as much as possible .
#
# @return New value of tolerance.
def updateTolerance(self):
"""
Compute possible tolerance for the shape,
minimize tolerance of shape as well as tolerance of sub-shapes as much as possible.
Returns:
New value of tolerance.
Example of usage:
Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200)
cc = CheckConformity(Box_1, geompy)
toler = cc.updateTolerance()
"""
anOp = self.geompyD.GetIMeasureOperations()
self.myIsChecked = False
print(anOp.updateTolerance(self.myShape))