0022762: [EDF] Fast detection of face/face face/solid solid/solid interference

- Part 2: introduce CheckSelfIntersectionsFast function
This commit is contained in:
akl 2015-04-28 12:21:22 +04:00 committed by vsr
parent b46831ede7
commit 7c036f24ff
21 changed files with 719 additions and 159 deletions

View File

@ -56,6 +56,7 @@ SET(GOOD_TESTS
center_of_mass.py center_of_mass.py
check_compound_of_blocks.py check_compound_of_blocks.py
check_self_intersections.py check_self_intersections.py
check_self_intersections_fast.py
check_shape.py check_shape.py
complex_objs_ex01.py complex_objs_ex01.py
complex_objs_ex02.py complex_objs_ex02.py

View File

@ -7,9 +7,15 @@ from salome.geom import geomBuilder
geompy = geomBuilder.New(salome.myStudy) geompy = geomBuilder.New(salome.myStudy)
# create a box # create a box
box = geompy.MakeBoxDXDYDZ(100,30,100) box = geompy.MakeBoxDXDYDZ(100,100,100)
IsValid = geompy.CheckSelfIntersections(box) # create a cylinder
if IsValid == 0: cylinder = geompy.MakeCylinderRH(100, 300)
raise RuntimeError, "Box with self-intersections created" # make a compound
compound = geompy.MakeCompound([box, cylinder])
# check self-intersection
IsValid = geompy.CheckSelfIntersections(compound)
if not IsValid:
print "Shape is self-intersected!"
else: else:
print "\nBox is valid" print "No self-intersection detected in a shape"

View File

@ -0,0 +1,21 @@
# Detect Self-intersections fast
import salome
salome.salome_init()
import GEOM
from salome.geom import geomBuilder
geompy = geomBuilder.New(salome.myStudy)
# create a box
box = geompy.MakeBoxDXDYDZ(100,100,100)
# create a cylinder
cylinder = geompy.MakeCylinderRH(100, 300)
# make a compound
compound = geompy.MakeCompound([box, cylinder])
# check self-intersection
IsValid = geompy.CheckSelfIntersectionsFast(compound)
if not IsValid:
print "Shape is self-intersected!"
else:
print "No self-intersection detected in a shape"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View File

@ -2,6 +2,14 @@
\page check_self_intersections_page Detect Self-intersections \page check_self_intersections_page Detect Self-intersections
\n To <b>Detect Self-intersections</b> in the <b>Main Menu</b> select
<b>Inspection - > Detect Self-intersections</b>.
There are two ways to check self-intersections.
\anchor check_self_intersections_topological
<br><h3>Check topological intersections</h2>
This operation checks the topology of the selected shape to detect self-intersections. This operation checks the topology of the selected shape to detect self-intersections.
\image html measures11.png \image html measures11.png
@ -29,5 +37,28 @@ where: \n
See also a \ref tui_check_self_intersections_page "TUI example". See also a \ref tui_check_self_intersections_page "TUI example".
\anchor check_self_intersections_fast
<br><h3>Fast intersection</h2>
This operations allows to quickly detect self-interferences of the given shape by means of algorithm based on mesh intersections.
\image html measures13.png
This algorithm works on the faces level, i.e. it computes only face-to-face intersections. No additional types of intersections is computed.
This case can be useful in order to detect all the intersections between the subshapes of type "surface" inside assembly.
Quality of result will depend on the quality of tesselation (managed via the deflection parameter). However, small values of deflection can
significantly decrease performance of the algorithm.
Nevertheless, performance of Fast Intersect algorithm is much higher than topological intersection.
\n <b>Result:</b> Boolean.
\n <b>TUI Command:</b> <em>geompy.CheckSelfIntersectionsFast(theShape, theDeflection, theTolerance),</em> \n
where: \n
\em theShape is the shape checked for validity. \n
\em theDeflection is a linear deflection coefficient that specifies quality of tesselation. If theDeflection <= 0, default deflection 0.001 is used.
\em theTolerance Specifies a distance between shapes used for detecting gaps:
- if theTolerance <= 0, algorithm detects intersections;
- if theTolerance > 0, algorithm detects gaps.
See also a \ref tui_check_self_intersections_fast_page "TUI example".
*/ */

View File

@ -0,0 +1,6 @@
/*!
\page tui_check_self_intersections_fast_page Detect Self-intersections fast
\tui_script{check_self_intersections_fast.py}
*/

View File

@ -19,6 +19,7 @@
<li>\subpage tui_check_compound_of_blocks_page</li> <li>\subpage tui_check_compound_of_blocks_page</li>
<li>\subpage tui_get_non_blocks_page</li> <li>\subpage tui_get_non_blocks_page</li>
<li>\subpage tui_check_self_intersections_page</li> <li>\subpage tui_check_self_intersections_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>
</ul> </ul>

View File

@ -17,7 +17,10 @@
\until Detect Self-intersections \until Detect Self-intersections
\anchor swig_CheckSelfIntersections \anchor swig_CheckSelfIntersections
\until Detect Fast intersection \until Detect Self-intersections fast
\anchor swig_CheckSelfIntersectionsFast
\until Fast intersection
\anchor swig_FastIntersection \anchor swig_FastIntersection
\until WhatIs \until WhatIs

View File

@ -4448,6 +4448,21 @@ module GEOM
in long theCheckLevel, in long theCheckLevel,
out ListOfLong theIntersections); out ListOfLong theIntersections);
/*!
* \brief Detect self-intersections of the given shape with algorithm based on mesh intersections.
* \param theShape Shape to check validity of.
* \param theDeflection Linear deflection coefficient that specifies quality of tesselation.
* \param theTolerance Specifies a distance between sub-shapes used for detecting gaps:
* - if \a theTolerance <= 0, algorithm detects intersections
* - if \a theTolerance > 0, algorithm detects gaps
* \param theIntersections Output. List of intersected sub-shapes IDs, it contains pairs of IDs.
* \return TRUE, if the shape does not have any self-intersections.
*/
boolean CheckSelfIntersectionsFast (in GEOM_Object theShape,
in float theDeflection,
in double theTolerance,
out ListOfLong theIntersections);
/*! /*!
* \brief Detect intersections of the given shapes with algorithm based on mesh intersections. * \brief Detect intersections of the given shapes with algorithm based on mesh intersections.
* \param theShape1 First source object * \param theShape1 First source object

View File

@ -7274,6 +7274,10 @@ Do you want to create new material?</translation>
</context> </context>
<context> <context>
<name>MeasureGUI_CheckSelfIntersectionsDlg</name> <name>MeasureGUI_CheckSelfIntersectionsDlg</name>
<message>
<source>GEOM_CHECK_INTERSECT_TYPE</source>
<translation>Self-intersection Detection Type</translation>
</message>
<message> <message>
<source>GEOM_CHECK_INTE_INTERSECTIONS</source> <source>GEOM_CHECK_INTE_INTERSECTIONS</source>
<translation>Self-intersections</translation> <translation>Self-intersections</translation>
@ -7338,6 +7342,14 @@ Do you want to create new material?</translation>
<source>GEOM_CHECK_INTE_ALL</source> <source>GEOM_CHECK_INTE_ALL</source>
<translation>Face to Face + all above</translation> <translation>Face to Face + all above</translation>
</message> </message>
<message>
<source>GEOM_CHECK_INT_DEFLECT</source>
<translation>Deflection coefficient</translation>
</message>
<message>
<source>GEOM_CHECK_INT_DETECT_GAPS</source>
<translation>Detect gaps with tolerance</translation>
</message>
</context> </context>
<context> <context>
<name>MeasureGUI_FastCheckIntersectionsDlg</name> <name>MeasureGUI_FastCheckIntersectionsDlg</name>

View File

@ -7274,6 +7274,10 @@ Voulez-vous en créer un nouveau ?</translation>
</context> </context>
<context> <context>
<name>MeasureGUI_CheckSelfIntersectionsDlg</name> <name>MeasureGUI_CheckSelfIntersectionsDlg</name>
<message>
<source>GEOM_CHECK_INTERSECT_TYPE</source>
<translation type="unfinished">Self-intersection Detection Type</translation>
</message>
<message> <message>
<source>GEOM_CHECK_INTE_INTERSECTIONS</source> <source>GEOM_CHECK_INTE_INTERSECTIONS</source>
<translation>Auto-intersections</translation> <translation>Auto-intersections</translation>
@ -7338,6 +7342,14 @@ Voulez-vous en créer un nouveau ?</translation>
<source>GEOM_CHECK_INTE_ALL</source> <source>GEOM_CHECK_INTE_ALL</source>
<translation>Face à Face + tout au-delà</translation> <translation>Face à Face + tout au-delà</translation>
</message> </message>
<message>
<source>GEOM_CHECK_INT_DEFLECT</source>
<translation type="unfinished">Deflection coefficient</translation>
</message>
<message>
<source>GEOM_CHECK_INT_DETECT_GAPS</source>
<translation type="unfinished">Detect gaps with tolerance</translation>
</message>
</context> </context>
<context> <context>
<name>MeasureGUI_FastCheckIntersectionsDlg</name> <name>MeasureGUI_FastCheckIntersectionsDlg</name>

View File

@ -7271,6 +7271,10 @@
</context> </context>
<context> <context>
<name>MeasureGUI_CheckSelfIntersectionsDlg</name> <name>MeasureGUI_CheckSelfIntersectionsDlg</name>
<message>
<source>GEOM_CHECK_INTERSECT_TYPE</source>
<translation type="unfinished">Self-intersection Detection Type</translation>
</message>
<message> <message>
<source>GEOM_CHECK_INTE_INTERSECTIONS</source> <source>GEOM_CHECK_INTE_INTERSECTIONS</source>
<translation></translation> <translation></translation>
@ -7335,6 +7339,14 @@
<source>GEOM_CHECK_INTE_ALL</source> <source>GEOM_CHECK_INTE_ALL</source>
<translation></translation> <translation></translation>
</message> </message>
<message>
<source>GEOM_CHECK_INT_DEFLECT</source>
<translation type="unfinished">Deflection coefficient</translation>
</message>
<message>
<source>GEOM_CHECK_INT_DETECT_GAPS</source>
<translation type="unfinished">Detect gaps with tolerance</translation>
</message>
</context> </context>
<context> <context>
<name>MeasureGUI_FastCheckIntersectionsDlg</name> <name>MeasureGUI_FastCheckIntersectionsDlg</name>

View File

@ -50,8 +50,9 @@
#include <BRepClass3d_SolidClassifier.hxx> #include <BRepClass3d_SolidClassifier.hxx>
#include <BRepClass_FaceClassifier.hxx> #include <BRepClass_FaceClassifier.hxx>
#include <BRepExtrema_DistShapeShape.hxx> #include <BRepExtrema_DistShapeShape.hxx>
#if OCC_VERSION_LARGE > 0x06080000
#include <BRepExtrema_ShapeProximity.hxx> #include <BRepExtrema_ShapeProximity.hxx>
#if OCC_VERSION_LARGE > 0x06090000
#include <BRepExtrema_SelfIntersection.hxx>
#endif #endif
#include <BRepGProp.hxx> #include <BRepGProp.hxx>
#include <BRepTools.hxx> #include <BRepTools.hxx>
@ -71,10 +72,13 @@
#include <TopoDS_Edge.hxx> #include <TopoDS_Edge.hxx>
#include <TopTools_IndexedMapOfShape.hxx> #include <TopTools_IndexedMapOfShape.hxx>
#include <TopTools_DataMapIteratorOfDataMapOfIntegerListOfShape.hxx> #include <TopTools_DataMapIteratorOfDataMapOfIntegerListOfShape.hxx>
#include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx> #include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_ListOfShape.hxx> #include <TopTools_ListOfShape.hxx>
#include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
#include <set>
//============================================================================= //=============================================================================
/*! /*!
* Constructor * Constructor
@ -1510,7 +1514,6 @@ bool GEOMImpl_IMeasureOperations::CheckSelfIntersections
Handle(TColStd_HSequenceOfInteger)& theIntersections) Handle(TColStd_HSequenceOfInteger)& theIntersections)
{ {
SetErrorCode(KO); SetErrorCode(KO);
bool isGood = false;
if (theIntersections.IsNull()) if (theIntersections.IsNull())
theIntersections = new TColStd_HSequenceOfInteger; theIntersections = new TColStd_HSequenceOfInteger;
@ -1518,13 +1521,13 @@ bool GEOMImpl_IMeasureOperations::CheckSelfIntersections
theIntersections->Clear(); theIntersections->Clear();
if (theShape.IsNull()) if (theShape.IsNull())
return isGood; return false;
Handle(GEOM_Function) aRefShape = theShape->GetLastFunction(); Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
if (aRefShape.IsNull()) return isGood; if (aRefShape.IsNull()) return false;
TopoDS_Shape aShape = aRefShape->GetValue(); TopoDS_Shape aShape = aRefShape->GetValue();
if (aShape.IsNull()) return isGood; if (aShape.IsNull()) return false;
// 0. Prepare data // 0. Prepare data
TopoDS_Shape aScopy; TopoDS_Shape aScopy;
@ -1546,7 +1549,6 @@ bool GEOMImpl_IMeasureOperations::CheckSelfIntersections
aCSI.Perform(); aCSI.Perform();
Standard_Integer iErr = aCSI.ErrorStatus(); Standard_Integer iErr = aCSI.ErrorStatus();
isGood = true;
// //
Standard_Integer aNbS, n1, n2; Standard_Integer aNbS, n1, n2;
BOPDS_MapIteratorMapOfPassKey aItMPK; BOPDS_MapIteratorMapOfPassKey aItMPK;
@ -1570,14 +1572,82 @@ bool GEOMImpl_IMeasureOperations::CheckSelfIntersections
theIntersections->Append(anIndices.FindIndex(aS1)); theIntersections->Append(anIndices.FindIndex(aS1));
theIntersections->Append(anIndices.FindIndex(aS2)); theIntersections->Append(anIndices.FindIndex(aS2));
isGood = false;
} }
if (!iErr) { if (!iErr) {
SetErrorCode(OK); SetErrorCode(OK);
} }
return isGood; return theIntersections->IsEmpty();
}
//=============================================================================
/*!
* CheckSelfIntersectionsFast
*/
//=============================================================================
bool GEOMImpl_IMeasureOperations::CheckSelfIntersectionsFast
(Handle(GEOM_Object) theShape,
float theDeflection, double theTolerance,
Handle(TColStd_HSequenceOfInteger)& theIntersections)
{
SetErrorCode(KO);
if (theIntersections.IsNull())
theIntersections = new TColStd_HSequenceOfInteger;
else
theIntersections->Clear();
if (theShape.IsNull())
return false;
Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
if (aRefShape.IsNull()) return false;
TopoDS_Shape aShape = aRefShape->GetValue();
if (aShape.IsNull()) return false;
// Prepare data
TopoDS_Shape aScopy;
GEOMAlgo_AlgoTools::CopyShape(aShape, aScopy);
GEOMUtils::MeshShape(aScopy, theDeflection);
// Map sub-shapes and their indices
TopTools_IndexedMapOfShape anIndices;
TopExp::MapShapes(aScopy, anIndices);
#if OCC_VERSION_LARGE > 0x06090000
// Checker of fast interferences
BRepExtrema_SelfIntersection aTool(aScopy, (theTolerance <= 0.) ? 0.0 : theTolerance);
// Launch the checker
aTool.Perform();
const BRepExtrema_OverlapTool::OverlapSubShapes& intersections = aTool.OverlapElements();
std::set<Standard_Integer> processed;
for (BRepExtrema_OverlapTool::OverlapSubShapes::Iterator it(intersections); it.More(); it.Next()) {
Standard_Integer idxLeft = it.Key();
if (processed.count(idxLeft) > 0) continue; // already added
processed.insert(idxLeft);
const TColStd_PackedMapOfInteger& overlaps = it.Value();
for (TColStd_MapIteratorOfPackedMapOfInteger subit(overlaps); subit.More(); subit.Next()) {
Standard_Integer idxRight = subit.Key();
if (processed.count(idxRight) > 0) continue; // already added
const TopoDS_Shape& aS1 = aTool.GetSubShape(idxLeft);
const TopoDS_Shape& aS2 = aTool.GetSubShape(idxRight);
theIntersections->Append(anIndices.FindIndex(aS1));
theIntersections->Append(anIndices.FindIndex(aS2));
}
}
if (aTool.IsDone())
SetErrorCode(OK);
#endif
return theIntersections->IsEmpty();
} }
//============================================================================= //=============================================================================
@ -1593,8 +1663,6 @@ bool GEOMImpl_IMeasureOperations::FastIntersect (Handle(GEOM_Object) theShape1,
SetErrorCode(KO); SetErrorCode(KO);
bool isGood = false; bool isGood = false;
#if OCC_VERSION_LARGE > 0x06080000
if (theIntersections1.IsNull()) if (theIntersections1.IsNull())
theIntersections1 = new TColStd_HSequenceOfInteger; theIntersections1 = new TColStd_HSequenceOfInteger;
else else
@ -1646,12 +1714,22 @@ bool GEOMImpl_IMeasureOperations::FastIntersect (Handle(GEOM_Object) theShape1,
aBSP.Perform(); aBSP.Perform();
// 2. Get sets of IDs of overlapped faces // 2. Get sets of IDs of overlapped faces
for (BRepExtrema_OverlappedSubShapes::Iterator anIt1 (aBSP.OverlapSubShapes1()); anIt1.More(); anIt1.Next()) { #if OCC_VERSION_LARGE > 0x06090000
for (BRepExtrema_OverlapTool::OverlapSubShapes::Iterator anIt1 (aBSP.OverlapSubShapes1()); anIt1.More(); anIt1.Next())
#else
for (BRepExtrema_OverlappedSubShapes::Iterator anIt1 (aBSP.OverlapSubShapes1()); anIt1.More(); anIt1.Next())
#endif
{
const TopoDS_Shape& aS1 = aBSP.GetSubShape1(anIt1.Key()); const TopoDS_Shape& aS1 = aBSP.GetSubShape1(anIt1.Key());
theIntersections1->Append(anIndices1.FindIndex(aS1)); theIntersections1->Append(anIndices1.FindIndex(aS1));
} }
for (BRepExtrema_OverlappedSubShapes::Iterator anIt2 (aBSP.OverlapSubShapes2()); anIt2.More(); anIt2.Next()) { #if OCC_VERSION_LARGE > 0x06090000
for (BRepExtrema_OverlapTool::OverlapSubShapes::Iterator anIt2 (aBSP.OverlapSubShapes2()); anIt2.More(); anIt2.Next())
#else
for (BRepExtrema_OverlappedSubShapes::Iterator anIt2 (aBSP.OverlapSubShapes2()); anIt2.More(); anIt2.Next())
#endif
{
const TopoDS_Shape& aS2 = aBSP.GetSubShape2(anIt2.Key()); const TopoDS_Shape& aS2 = aBSP.GetSubShape2(anIt2.Key());
theIntersections2->Append(anIndices2.FindIndex(aS2)); theIntersections2->Append(anIndices2.FindIndex(aS2));
} }
@ -1661,8 +1739,6 @@ bool GEOMImpl_IMeasureOperations::FastIntersect (Handle(GEOM_Object) theShape1,
if (aBSP.IsDone()) if (aBSP.IsDone())
SetErrorCode(OK); SetErrorCode(OK);
#endif // OCC_VERSION_LARGE > 0x06080000
return isGood; return isGood;
} }

View File

@ -158,6 +158,11 @@ class GEOMImpl_IMeasureOperations : public GEOM_IOperations {
const SICheckLevel theCheckLevel, const SICheckLevel theCheckLevel,
Handle(TColStd_HSequenceOfInteger)& theIntersections); Handle(TColStd_HSequenceOfInteger)& theIntersections);
Standard_EXPORT bool CheckSelfIntersectionsFast (Handle(GEOM_Object) theShape,
float deflection,
double tolerance,
Handle(TColStd_HSequenceOfInteger)& theIntersections);
Standard_EXPORT bool FastIntersect (Handle(GEOM_Object) theShape1, Handle(GEOM_Object) theShape2, Standard_EXPORT bool FastIntersect (Handle(GEOM_Object) theShape1, Handle(GEOM_Object) theShape2,
double tolerance, float deflection, double tolerance, float deflection,
Handle(TColStd_HSequenceOfInteger)& theIntersections1, Handle(TColStd_HSequenceOfInteger)& theIntersections1,

View File

@ -765,6 +765,49 @@ CORBA::Boolean GEOM_IMeasureOperations_i::CheckSelfIntersections (GEOM::GEOM_Obj
return isGood; return isGood;
} }
//=============================================================================
/*!
* CheckSelfIntersectionsFast
*/
//=============================================================================
CORBA::Boolean GEOM_IMeasureOperations_i::CheckSelfIntersectionsFast
(GEOM::GEOM_Object_ptr theShape,
CORBA::Float theDeflection,
CORBA::Double theTolerance,
GEOM::ListOfLong_out theIntersections)
{
// Set a not done flag
GetOperations()->SetNotDone();
bool isGood = false;
// Allocate the CORBA arrays
GEOM::ListOfLong_var anIntegersArray = new GEOM::ListOfLong();
// Get the reference shape
Handle(GEOM_Object) aShape = GetObjectImpl(theShape);
if (!aShape.IsNull()) {
Handle(TColStd_HSequenceOfInteger) anIntegers = new TColStd_HSequenceOfInteger;
// Detect self-intersections
isGood = GetOperations()->CheckSelfIntersectionsFast
(aShape, theDeflection, theTolerance, anIntegers);
int nbInts = anIntegers->Length();
anIntegersArray->length(nbInts);
for (int ii = 0; ii < nbInts; ii++) {
anIntegersArray[ii] = anIntegers->Value(ii + 1);
}
}
// Initialize out-parameters with local arrays
theIntersections = anIntegersArray._retn();
return isGood;
}
//============================================================================= //=============================================================================
/*! /*!
* FastIntersect * FastIntersect

View File

@ -100,6 +100,11 @@ class GEOM_I_EXPORT GEOM_IMeasureOperations_i :
CORBA::Long theCheckLevel, CORBA::Long theCheckLevel,
GEOM::ListOfLong_out theIntersections); GEOM::ListOfLong_out theIntersections);
CORBA::Boolean CheckSelfIntersectionsFast (GEOM::GEOM_Object_ptr theShape,
CORBA::Float theDeflection,
CORBA::Double theTolerance,
GEOM::ListOfLong_out theIntersections);
CORBA::Boolean FastIntersect (GEOM::GEOM_Object_ptr theShape1, CORBA::Boolean FastIntersect (GEOM::GEOM_Object_ptr theShape1,
GEOM::GEOM_Object_ptr theShape2, GEOM::GEOM_Object_ptr theShape2,
CORBA::Double theTolerance, CORBA::Double theTolerance,

View File

@ -33,8 +33,12 @@ def TestMeasureOperations (geompy, math):
p678 = geompy.MakeVertex(60, 70, 80) p678 = geompy.MakeVertex(60, 70, 80)
p789 = geompy.MakeVertex(70, 80, 90) p789 = geompy.MakeVertex(70, 80, 90)
vz = geompy.MakeVectorDXDYDZ(0, 0, 1)
cube = geompy.MakeBoxTwoPnt(p678, p789) cube = geompy.MakeBoxTwoPnt(p678, p789)
cylinder = geompy.MakeCylinder(p0, vz, 5, 70)
####### PointCoordinates ####### ####### PointCoordinates #######
Coords = geompy.PointCoordinates(p137) Coords = geompy.PointCoordinates(p137)
@ -52,18 +56,20 @@ def TestMeasureOperations (geompy, math):
####### Detect Self-intersections ####### ####### Detect Self-intersections #######
[Face_1,Face_2] = geompy.SubShapes(box, [33, 23]) selfIntersected = geompy.MakeCompound([box, cylinder])
Translation_1 = geompy.MakeTranslation(Face_1, 5, -15, -40) if geompy.CheckSelfIntersections(selfIntersected):
Compound_1 = geompy.MakeCompound([Face_2, Translation_1])
if geompy.CheckSelfIntersections(Compound_1) == True:
raise RuntimeError, "Existing self-intersection is not detected" raise RuntimeError, "Existing self-intersection is not detected"
####### Detect Fast intersection ####### ####### Detect Self-intersections fast #######
if salome_version.getXVersion() > "0x70501": if salome_version.getXVersion() > "0x70600":
cylinder = geompy.MakeCylinderRH(100, 300) if geompy.CheckSelfIntersectionsFast(selfIntersected):
if geompy.FastIntersect(box, cylinder)[0] == False: raise RuntimeError, "Existing self-intersection is not detected"
raise RuntimeError, "Existing intersection is not detected"
####### Fast intersection #######
if not geompy.FastIntersect(box, cylinder)[0]:
raise RuntimeError, "Existing intersection is not detected"
####### WhatIs ####### ####### WhatIs #######

View File

@ -11257,6 +11257,37 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen):
RaiseIfFailed("CheckSelfIntersections", self.MeasuOp) RaiseIfFailed("CheckSelfIntersections", self.MeasuOp)
return IsValid return IsValid
## Detect self-intersections of the given shape with algorithm based on mesh intersections.
# @param theShape Shape to check.
# @param theDeflection Linear deflection coefficient that specifies quality of tesselation:
# - if \a theDeflection <= 0, default deflection 0.001 is used
# @param theTolerance Specifies a distance between sub-shapes used for detecting gaps:
# - if \a theTolerance <= 0, algorithm detects intersections (default behavior)
# - if \a theTolerance > 0, algorithm detects gaps
# @return TRUE, if the shape contains no self-intersections.
#
# @ref tui_check_self_intersections_fast_page "Example"
@ManageTransactions("MeasuOp")
def CheckSelfIntersectionsFast(self, theShape, theDeflection = 0.001, theTolerance = 0.0):
"""
Detect self-intersections of the given shape with algorithm based on mesh intersections.
Parameters:
theShape Shape to check.
theDeflection Linear deflection coefficient that specifies quality of tesselation:
- if theDeflection <= 0, default deflection 0.001 is used
theTolerance Specifies a distance between shapes used for detecting gaps:
- if theTolerance <= 0, algorithm detects intersections (default behavior)
- if theTolerance > 0, algorithm detects gaps
Returns:
TRUE, if the shape contains no self-intersections.
"""
# Example: see GEOM_TestMeasures.py
(IsValid, Pairs) = self.MeasuOp.CheckSelfIntersectionsFast(theShape, theDeflection, theTolerance)
RaiseIfFailed("CheckSelfIntersectionsFast", self.MeasuOp)
return IsValid
## Detect intersections of the given shapes with algorithm based on mesh intersections. ## Detect intersections of the given shapes with algorithm based on mesh intersections.
# @param theShape1 First source object # @param theShape1 First source object
# @param theShape2 Second source object # @param theShape2 Second source object

View File

@ -26,6 +26,7 @@
#include "MeasureGUI_CheckSelfIntersectionsDlg.h" #include "MeasureGUI_CheckSelfIntersectionsDlg.h"
#include "MeasureGUI.h" #include "MeasureGUI.h"
#include <SUIT_MessageBox.h>
#include <SUIT_OverrideCursor.h> #include <SUIT_OverrideCursor.h>
#include <SUIT_Session.h> #include <SUIT_Session.h>
#include <SUIT_ResourceMgr.h> #include <SUIT_ResourceMgr.h>
@ -58,80 +59,144 @@
//================================================================================= //=================================================================================
MeasureGUI_CheckSelfIntersectionsDlg::MeasureGUI_CheckSelfIntersectionsDlg (GeometryGUI* GUI, QWidget* parent) MeasureGUI_CheckSelfIntersectionsDlg::MeasureGUI_CheckSelfIntersectionsDlg (GeometryGUI* GUI, QWidget* parent)
: GEOMBase_Skeleton (GUI, parent, false), : GEOMBase_Skeleton (GUI, parent, false),
myTextView (0), myTextView1 (0),
mySelButton (0), myTextView2 (0),
myEditObjName (0), mySelButton1 (0),
mySelButton2 (0),
myEditObjName1 (0),
myEditObjName2 (0),
myLevelBox (0), myLevelBox (0),
myComputeButton (0), myComputeButton1 (0),
myInteList (0), myComputeButton2 (0),
myShapeList (0) myInteList1 (0),
myShapeList1 (0),
myInteList2 (0),
myShapeList2 (0),
myCurrConstrId (-1)
{ {
SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr(); SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
QPixmap image0 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_CHECK_SELF_INTERSECTIONS"))); QPixmap image0 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_CHECK_SELF_INTERSECTIONS")));
QPixmap image1 (aResMgr->loadPixmap("GEOM", tr("ICON_SELECT"))); QPixmap image1 (aResMgr->loadPixmap("GEOM", tr("ICON_SELECT")));
QPixmap image2 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_FAST_CHECK_INTERSECTIONS")));
setWindowTitle(tr("GEOM_CHECK_SELF_INTERSECTIONS")); setWindowTitle(tr("GEOM_CHECK_SELF_INTERSECTIONS"));
/***************************************************************/ /***************************************************************/
mainFrame()->GroupConstructors->setTitle(tr("GEOM_CHECK_SELF_INTERSECTIONS")); mainFrame()->GroupConstructors->setTitle(tr("GEOM_CHECK_INTERSECT_TYPE"));
mainFrame()->RadioButton1->setIcon(image0); mainFrame()->RadioButton1->setIcon(image0);
mainFrame()->RadioButton2->setAttribute( Qt::WA_DeleteOnClose ); mainFrame()->RadioButton2->setIcon(image2);;
mainFrame()->RadioButton2->close();
mainFrame()->RadioButton3->setAttribute( Qt::WA_DeleteOnClose ); mainFrame()->RadioButton3->setAttribute( Qt::WA_DeleteOnClose );
mainFrame()->RadioButton3->close(); mainFrame()->RadioButton3->close();
QGroupBox *aGrp = new QGroupBox(tr("GEOM_CHECK_INFOS")); /***************************************************************/
QLabel *anObjLbl = new QLabel(tr("GEOM_OBJECT")); /* SIMPLE SELF-INTERSECTION constructor
QLabel *anInteLbl = new QLabel(tr("GEOM_CHECK_INTE_INTERSECTIONS")); /***************************************************************/
QLabel *aShapeLbl = new QLabel(tr("GEOM_CHECK_INTE_SUBSHAPES")); mySimpleGrp = new QGroupBox(tr("GEOM_CHECK_INFOS"));
QLabel *aLevelLbl = new QLabel(tr("GEOM_CHECK_INTE_CHECK_LEVEL")); QLabel *anObjLbl = new QLabel(tr("GEOM_OBJECT"));
QLabel *aSummaryLbl = new QLabel(tr("GEOM_CHECK_INTE_SUMMARY")); QLabel *anInteLbl = new QLabel(tr("GEOM_CHECK_INTE_INTERSECTIONS"));
QLabel *aShapeLbl = new QLabel(tr("GEOM_CHECK_INTE_SUBSHAPES"));
QLabel *aLevelLbl = new QLabel(tr("GEOM_CHECK_INTE_CHECK_LEVEL"));
QLabel *aSummaryLbl1 = new QLabel(tr("GEOM_CHECK_INTE_SUMMARY"));
QFont aFont (TEXTEDIT_FONT_FAMILY, TEXTEDIT_FONT_SIZE); QFont aFont (TEXTEDIT_FONT_FAMILY, TEXTEDIT_FONT_SIZE);
aFont.setStyleHint(QFont::TypeWriter, QFont::PreferAntialias); aFont.setStyleHint(QFont::TypeWriter, QFont::PreferAntialias);
myTextView = new QTextBrowser; myTextView1 = new QTextBrowser;
myTextView->setReadOnly(true); myTextView1->setReadOnly(true);
myTextView->setFont(aFont); myTextView1->setFont(aFont);
mySelButton = new QPushButton; mySelButton1 = new QPushButton;
mySelButton->setIcon(image1); mySelButton1->setIcon(image1);
mySelButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); mySelButton1->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
myEditObjName = new QLineEdit; myEditObjName1 = new QLineEdit;
myEditObjName->setReadOnly(true); myEditObjName1->setReadOnly(true);
myLevelBox = new QComboBox; myLevelBox = new QComboBox;
myComputeButton = new QPushButton(tr("GEOM_CHECK_INTE_COMPUTE")); myComputeButton1 = new QPushButton(tr("GEOM_CHECK_INTE_COMPUTE"));
myInteList = new QListWidget; myInteList1 = new QListWidget;
myInteList->setSelectionMode(QAbstractItemView::ExtendedSelection); myInteList1->setSelectionMode(QAbstractItemView::ExtendedSelection);
myShapeList = new QListWidget; myShapeList1 = new QListWidget;
myShapeList->setSelectionMode(QAbstractItemView::ExtendedSelection); myShapeList1->setSelectionMode(QAbstractItemView::ExtendedSelection);
QGridLayout *aGrpLayout = new QGridLayout(aGrp); QGridLayout *aGrpLayout1 = new QGridLayout(mySimpleGrp);
aGrpLayout->setMargin(9); aGrpLayout1->setMargin(9);
aGrpLayout->setSpacing(6); aGrpLayout1->setSpacing(6);
aGrpLayout->addWidget(anObjLbl, 0, 0); aGrpLayout1->addWidget(anObjLbl, 0, 0);
aGrpLayout->addWidget(anInteLbl, 5, 0); aGrpLayout1->addWidget(mySelButton1, 0, 1);
aGrpLayout->addWidget(aShapeLbl, 5, 2); aGrpLayout1->addWidget(myEditObjName1, 0, 2);
aGrpLayout->addWidget(aLevelLbl, 1, 0); aGrpLayout1->addWidget(aLevelLbl, 1, 0);
aGrpLayout->addWidget(myLevelBox, 1, 1, 1, 2); aGrpLayout1->addWidget(myLevelBox, 1, 1, 1, 2);
aGrpLayout->addWidget(myComputeButton, 2, 0, 1, 3); aGrpLayout1->addWidget(myComputeButton1, 2, 0, 1, 3);
aGrpLayout->addWidget(aSummaryLbl, 3, 0); aGrpLayout1->addWidget(aSummaryLbl1, 3, 0);
aGrpLayout->addWidget(myTextView, 4, 0, 1, 3); aGrpLayout1->addWidget(myTextView1, 4, 0, 1, 3);
aGrpLayout->addWidget(mySelButton, 0, 1); aGrpLayout1->addWidget(anInteLbl, 5, 0);
aGrpLayout->addWidget(myEditObjName, 0, 2); aGrpLayout1->addWidget(aShapeLbl, 5, 2);
aGrpLayout->addWidget(myInteList, 6, 0, 1, 2); aGrpLayout1->addWidget(myInteList1, 6, 0, 1, 2);
aGrpLayout->addWidget(myShapeList, 6, 2); aGrpLayout1->addWidget(myShapeList1, 6, 2);
QVBoxLayout* layout = new QVBoxLayout (centralWidget());
layout->setMargin(0); layout->setSpacing(6);
layout->addWidget(aGrp);
/***************************************************************/ /***************************************************************/
/* FAST SELF-INTERSECTION constructor
/***************************************************************/
myFastGrp = new QGroupBox(tr("GEOM_CHECK_INFOS"), centralWidget());
QLabel *anObjLbl2 = new QLabel(tr("GEOM_OBJECT"), myFastGrp);
QLabel *aDeflectLbl = new QLabel(tr("GEOM_CHECK_INT_DEFLECT"), myFastGrp);
QLabel *aSummaryLbl2 = new QLabel(tr("GEOM_CHECK_INTE_SUMMARY"));
QLabel *anInteLbl2 = new QLabel(tr("GEOM_CHECK_INTE_INTERSECTIONS"), myFastGrp);
QLabel *aShapeLbl2 = new QLabel(tr("GEOM_CHECK_INTE_SUBSHAPES"), myFastGrp);
mySelButton2 = new QPushButton(myFastGrp);
mySelButton2->setIcon(image1);
mySelButton2->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
myEditObjName2 = new QLineEdit(myFastGrp);
myEditObjName2->setReadOnly(true);
myDeflection = new SalomeApp_DoubleSpinBox(myFastGrp);
myDetGaps = new QCheckBox(tr( "GEOM_CHECK_INT_DETECT_GAPS" ));
myTolerance = new SalomeApp_DoubleSpinBox(myFastGrp);
myComputeButton2 = new QPushButton(tr("GEOM_CHECK_INTE_COMPUTE"));
myTextView2 = new QTextBrowser;
myTextView2->setReadOnly(true);
myTextView2->setFont(aFont);
myInteList2 = new QListWidget(myFastGrp);
myInteList2->setSelectionMode(QAbstractItemView::ExtendedSelection);
myShapeList2 = new QListWidget(myFastGrp);
myShapeList2->setSelectionMode(QAbstractItemView::ExtendedSelection);
QGridLayout *aGrpLayout2 = new QGridLayout(myFastGrp);
aGrpLayout2->setMargin(9);
aGrpLayout2->setSpacing(6);
aGrpLayout2->addWidget(anObjLbl2, 0, 0);
aGrpLayout2->addWidget(mySelButton2, 0, 1);
aGrpLayout2->addWidget(myEditObjName2, 0, 2);
aGrpLayout2->addWidget(aDeflectLbl, 1, 0);
aGrpLayout2->addWidget(myDeflection, 1, 1, 1, 2);
aGrpLayout2->addWidget(myDetGaps, 2, 0);
aGrpLayout2->addWidget(myTolerance, 2, 1, 1, 2);
aGrpLayout2->addWidget(myComputeButton2, 3, 0, 1, 3);
aGrpLayout2->addWidget(aSummaryLbl2, 4, 0);
aGrpLayout2->addWidget(myTextView2, 5, 0, 1, 3);
aGrpLayout2->addWidget(anInteLbl2, 6, 0);
aGrpLayout2->addWidget(aShapeLbl2, 6, 1, 1, 2);
aGrpLayout2->addWidget(myInteList2, 7, 0);
aGrpLayout2->addWidget(myShapeList2, 7, 1, 1, 2);
/***************************************************************/
QVBoxLayout* layout2 = new QVBoxLayout (centralWidget());
layout2->setMargin(0); layout2->setSpacing(6);
layout2->addWidget(mySimpleGrp);
layout2->addWidget(myFastGrp);
/***************************************************************/
myHelpFileName = "check_self_intersections_page.html"; myHelpFileName = "check_self_intersections_page.html";
@ -161,32 +226,65 @@ void MeasureGUI_CheckSelfIntersectionsDlg::Init()
myLevelBox->insertItem(GEOM::SI_E_F, tr("GEOM_CHECK_INTE_E_F")); myLevelBox->insertItem(GEOM::SI_E_F, tr("GEOM_CHECK_INTE_E_F"));
myLevelBox->insertItem(GEOM::SI_ALL, tr("GEOM_CHECK_INTE_ALL")); myLevelBox->insertItem(GEOM::SI_ALL, tr("GEOM_CHECK_INTE_ALL"));
myLevelBox->setCurrentIndex(GEOM::SI_ALL); myLevelBox->setCurrentIndex(GEOM::SI_ALL);
myComputeButton1->setEnabled(false);
connect(mySelButton1, SIGNAL(clicked()),
this, SLOT(SetEditCurrentArgument()));
connect(myInteList1, SIGNAL(itemSelectionChanged()),
SLOT(onInteListSelectionChanged()));
connect(myShapeList1, SIGNAL(itemSelectionChanged()),
SLOT(onSubShapesListSelectionChanged()));
connect(myLevelBox, SIGNAL(currentIndexChanged(int)),
this, SLOT(clear()));
connect(myComputeButton1, SIGNAL(clicked()), this, SLOT(onCompute()));
/***************************************************************/
myObj2.nullify();
myEditObjName2->setText("");
myEditObjName2->setEnabled(true);
myDetGaps->setChecked(false);
initSpinBox(myTolerance, 0, MAX_NUMBER, 1);
myTolerance->setValue(0);
myTolerance->setEnabled(false);
myComputeButton2->setEnabled(false);
// Obtain deflection from preferences
SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
initSpinBox(myDeflection, 1e-3, 1.0, 1e-3);
myDeflection->setValue(qMax(1e-3, resMgr->doubleValue("Geometry", "deflection_coeff", 1e-3)));
connect( mySelButton2, SIGNAL(clicked()),
this, SLOT(SetEditCurrentArgument()));
connect( myDetGaps, SIGNAL(toggled(bool)), this, SLOT(OnGaps(bool)));
connect( myTolerance, SIGNAL(valueChanged(double)), this, SLOT(clear()));
connect( myDeflection, SIGNAL(valueChanged(double)), this, SLOT(clear()));
connect( myInteList2, SIGNAL(itemSelectionChanged()),
SLOT(onInteListSelectionChanged()));
connect( myShapeList2, SIGNAL(itemSelectionChanged()),
SLOT(onSubShapesListSelectionChanged()));
connect( myComputeButton2, SIGNAL(clicked()), this, SLOT(onCompute()));
/***************************************************************/
connect(this, SIGNAL(constructorsClicked(int)),
this, SLOT(ConstructorsClicked(int)));
connect(myGeomGUI, SIGNAL(SignalDeactivateActiveDialog()), connect(myGeomGUI, SIGNAL(SignalDeactivateActiveDialog()),
this, SLOT(DeactivateActiveDialog())); this, SLOT(DeactivateActiveDialog()));
connect(myGeomGUI, SIGNAL(SignalCloseAllDialogs()), connect(myGeomGUI, SIGNAL(SignalCloseAllDialogs()),
this, SLOT(ClickOnCancel())); this, SLOT(ClickOnCancel()));
connect(buttonOk(), SIGNAL(clicked()), this, SLOT(ClickOnOk())); connect(buttonOk(), SIGNAL(clicked()), this, SLOT(ClickOnOk()));
connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply())); connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply()));
connect(mySelButton, SIGNAL(clicked()),
this, SLOT(SetEditCurrentArgument()));
connect(myInteList, SIGNAL(itemSelectionChanged()),
SLOT(onInteListSelectionChanged()));
connect(myShapeList, SIGNAL(itemSelectionChanged()),
SLOT(onSubShapesListSelectionChanged()));
connect(myLevelBox, SIGNAL(currentIndexChanged(int)),
this, SLOT(clear()));
connect(myComputeButton, SIGNAL(clicked()), this, SLOT(onCompute()));
LightApp_SelectionMgr* aSel = myGeomGUI->getApp()->selectionMgr(); LightApp_SelectionMgr* aSel = myGeomGUI->getApp()->selectionMgr();
connect(aSel, SIGNAL(currentSelectionChanged()), connect(aSel, SIGNAL(currentSelectionChanged()),
this, SLOT(SelectionIntoArgument())); this, SLOT(SelectionIntoArgument()));
initName( tr( "GEOM_SELF_INTERSECTION_NAME") ); initName( tr( "GEOM_SELF_INTERSECTION_NAME") );
buttonOk()->setEnabled(false); buttonOk()->setEnabled(false);
buttonApply()->setEnabled(false); buttonApply()->setEnabled(false);
myComputeButton->setEnabled(false);
ConstructorsClicked(0);
activateSelection(); activateSelection();
SelectionIntoArgument(); SelectionIntoArgument();
} }
@ -197,20 +295,56 @@ void MeasureGUI_CheckSelfIntersectionsDlg::Init()
//================================================================================= //=================================================================================
void MeasureGUI_CheckSelfIntersectionsDlg::clear() void MeasureGUI_CheckSelfIntersectionsDlg::clear()
{ {
myTextView->setText(""); getTextView()->setText("");
getComputeButton()->setEnabled(true);
myInteList->blockSignals(true); getInteList()->blockSignals(true);
myShapeList->blockSignals(true); getShapeList()->blockSignals(true);
myInteList->clear(); getInteList()->clear();
myShapeList->clear(); getShapeList()->clear();
myInteList->blockSignals(false); getInteList()->blockSignals(false);
myShapeList->blockSignals(false); getShapeList()->blockSignals(false);
erasePreview(); erasePreview();
buttonOk()->setEnabled(false); buttonOk()->setEnabled(false);
buttonApply()->setEnabled(false); buttonApply()->setEnabled(false);
myComputeButton->setEnabled(true); }
//=================================================================================
// function : ConstructorsClicked()
// purpose : Radio button management
//=================================================================================
void MeasureGUI_CheckSelfIntersectionsDlg::ConstructorsClicked(int constructorId)
{
if (myCurrConstrId == constructorId)
return;
disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0);
switch (constructorId) {
case 0:
mySimpleGrp->show();
myFastGrp->hide();
break;
case 1:
mySimpleGrp->hide();
myFastGrp->show();
break;
}
myCurrConstrId = constructorId;
connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()),
this, SLOT(SelectionIntoArgument()));
qApp->processEvents();
updateGeometry();
resize(minimumSizeHint());
processPreview();
//updateButtonState();
activateSelection();
SelectionIntoArgument();
} }
//================================================================================= //=================================================================================
@ -223,7 +357,7 @@ void MeasureGUI_CheckSelfIntersectionsDlg::onCompute()
QString anErrMsg(""); QString anErrMsg("");
if (!findSelfIntersections(hasSelfInte, anErrMsg)) { if (!findSelfIntersections(hasSelfInte, anErrMsg)) {
myTextView->setText(anErrMsg); getTextView()->setText(anErrMsg);
return; return;
} }
@ -243,12 +377,12 @@ void MeasureGUI_CheckSelfIntersectionsDlg::onCompute()
aMsg += anErrMsg; aMsg += anErrMsg;
} }
myTextView->setText(aMsg); getTextView()->setText(aMsg);
// Pairs // Pairs
QStringList anInteList; QStringList anInteList;
QString anInteStr (""); QString anInteStr ("");
int nbPairs = myInters->length()/2; int nbPairs = getInters()->length()/2;
for (int i = 1; i <= nbPairs; i++) { for (int i = 1; i <= nbPairs; i++) {
anInteStr = "Intersection # "; anInteStr = "Intersection # ";
@ -256,8 +390,8 @@ void MeasureGUI_CheckSelfIntersectionsDlg::onCompute()
anInteList.append(anInteStr); anInteList.append(anInteStr);
} }
myInteList->addItems(anInteList); getInteList()->addItems(anInteList);
myComputeButton->setEnabled(false); getComputeButton()->setEnabled(false);
} }
//================================================================================= //=================================================================================
@ -291,7 +425,23 @@ void MeasureGUI_CheckSelfIntersectionsDlg::DeactivateActiveDialog()
//================================================================================= //=================================================================================
void MeasureGUI_CheckSelfIntersectionsDlg::activateSelection() void MeasureGUI_CheckSelfIntersectionsDlg::activateSelection()
{ {
globalSelection(GEOM_ALLSHAPES); switch (getConstructorId()) {
case 0:
globalSelection(GEOM_ALLSHAPES);
break;
case 1:
TColStd_MapOfInteger aTypes;
aTypes.Add(GEOM_COMPOUND );
aTypes.Add(GEOM_SOLID );
aTypes.Add(GEOM_SHELL);
aTypes.Add(GEOM_FACE);
globalSelection(aTypes);
std::list<int> needTypes;
needTypes.push_back( TopAbs_FACE ), needTypes.push_back( TopAbs_SHELL ), needTypes.push_back( TopAbs_SOLID ), needTypes.push_back( TopAbs_COMPOUND );
localSelection(GEOM::GEOM_Object::_nil(), needTypes );
break;
}
} }
//================================================================================= //=================================================================================
@ -313,7 +463,11 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::ClickOnApply()
if ( !onAccept() ) if ( !onAccept() )
return false; return false;
clear();
initName(); initName();
ConstructorsClicked(getConstructorId());
return true; return true;
} }
@ -341,7 +495,7 @@ GEOM::GEOM_IOperations_ptr MeasureGUI_CheckSelfIntersectionsDlg::createOperation
//================================================================================= //=================================================================================
bool MeasureGUI_CheckSelfIntersectionsDlg::isValid( QString& ) bool MeasureGUI_CheckSelfIntersectionsDlg::isValid( QString& )
{ {
return !myObj->_is_nil(); return !getObj().isNull();
} }
//================================================================================= //=================================================================================
@ -350,37 +504,51 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::isValid( QString& )
//================================================================================= //=================================================================================
void MeasureGUI_CheckSelfIntersectionsDlg::SetEditCurrentArgument() void MeasureGUI_CheckSelfIntersectionsDlg::SetEditCurrentArgument()
{ {
myEditObjName->setFocus(); getEditObjName()->setFocus();
SelectionIntoArgument(); SelectionIntoArgument();
} }
//=================================================================================
// function : OnGaps()
// purpose :
//=================================================================================
void MeasureGUI_CheckSelfIntersectionsDlg::OnGaps(bool checked)
{
clear();
myTolerance->setEnabled(checked);
}
//================================================================================= //=================================================================================
// function : SelectionIntoArgument // function : SelectionIntoArgument
// purpose : // purpose :
//================================================================================= //=================================================================================
void MeasureGUI_CheckSelfIntersectionsDlg::SelectionIntoArgument() void MeasureGUI_CheckSelfIntersectionsDlg::SelectionIntoArgument()
{ {
QList<TopAbs_ShapeEnum> typesLst;
if ( getConstructorId() == 0 ) {
typesLst << TopAbs_COMPOUND
<< TopAbs_COMPSOLID
<< TopAbs_SOLID
<< TopAbs_SHELL
<< TopAbs_FACE
<< TopAbs_WIRE
<< TopAbs_EDGE
<< TopAbs_VERTEX
<< TopAbs_SHAPE;
} else {
typesLst << TopAbs_FACE
<< TopAbs_SHELL
<< TopAbs_SOLID
<< TopAbs_COMPOUND;
}
// Clear the dialog. // Clear the dialog.
clear(); clear();
myObj = GEOM::GEOM_Object::_nil();
LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr(); GEOM::GeomObjPtr aSelectedObject = getSelected( typesLst );
SALOME_ListIO aSelList;
aSelMgr->selectedObjects(aSelList);
GEOM::GEOM_Object_var aSelectedObject = GEOM::GEOM_Object::_nil(); (getConstructorId() == 0 ? myObj1 :myObj2) = aSelectedObject;
getEditObjName()->setText(getObj() ? GEOMBase::GetName(getObj().get()) : "");
if (aSelList.Extent() > 0) {
aSelectedObject = GEOMBase::ConvertIOinGEOMObject( aSelList.First() );
}
if (aSelectedObject->_is_nil()) {
myEditObjName->setText("");
return;
}
myObj = aSelectedObject;
myEditObjName->setText(GEOMBase::GetName(myObj));
} }
//================================================================================= //=================================================================================
@ -400,7 +568,7 @@ void MeasureGUI_CheckSelfIntersectionsDlg::enterEvent(QEvent *)
bool MeasureGUI_CheckSelfIntersectionsDlg::findSelfIntersections bool MeasureGUI_CheckSelfIntersectionsDlg::findSelfIntersections
(bool &HasSelfInte, QString &theErrMsg) (bool &HasSelfInte, QString &theErrMsg)
{ {
if (myObj->_is_nil()) { if (getObj()->_is_nil()) {
return false; return false;
} }
@ -413,10 +581,14 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::findSelfIntersections
SUIT_OverrideCursor wc; SUIT_OverrideCursor wc;
try { try {
HasSelfInte = !anOper->CheckSelfIntersections(myObj, aLevel, myInters); if ( getConstructorId() == 0 ) {
nbPairs = myInters->length()/2; HasSelfInte = !anOper->CheckSelfIntersections(myObj1.get(), aLevel, myInters1);
} else {
HasSelfInte = !anOper->CheckSelfIntersectionsFast(myObj2.get(), getDeflection(), getTolerance(), myInters2);
}
nbPairs = getInters()->length()/2;
if (nbPairs*2 != myInters->length()) { if (nbPairs*2 != getInters()->length()) {
isOK = false; isOK = false;
} }
} }
@ -426,7 +598,7 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::findSelfIntersections
} }
if (!anOper->IsDone()) { if (!anOper->IsDone()) {
if (myInters->length() == 0) { if (getInters()->length() == 0) {
theErrMsg = tr(anOper->GetErrorCode()); theErrMsg = tr(anOper->GetErrorCode());
isOK = false; isOK = false;
} else { } else {
@ -447,24 +619,24 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::findSelfIntersections
void MeasureGUI_CheckSelfIntersectionsDlg::onInteListSelectionChanged() void MeasureGUI_CheckSelfIntersectionsDlg::onInteListSelectionChanged()
{ {
erasePreview(); erasePreview();
myShapeList->clear(); getShapeList()->clear();
TopoDS_Shape aSelShape; TopoDS_Shape aSelShape;
if (!myObj->_is_nil() && GEOMBase::GetShape(myObj, aSelShape)) { if (!getObj()->_is_nil() && GEOMBase::GetShape(getObj().get(), aSelShape)) {
TopTools_IndexedMapOfShape anIndices; TopTools_IndexedMapOfShape anIndices;
TopExp::MapShapes(aSelShape, anIndices); TopExp::MapShapes(aSelShape, anIndices);
int nbSelected = myInteList->selectedItems().size(); int nbSelected = getInteList()->selectedItems().size();
for (int i = 0; i < myInteList->count(); i++) { for (int i = 0; i < getInteList()->count(); i++) {
if ( myInteList->item(i)->isSelected() ) { if ( getInteList()->item(i)->isSelected() ) {
if ( nbSelected > 1 ) if ( nbSelected > 1 )
myShapeList->addItem(QString("--- #%1 ---").arg(i+1)); getShapeList()->addItem(QString("--- #%1 ---").arg(i+1));
for (int j = 0; j < 2; j++) { for (int j = 0; j < 2; j++) {
TopoDS_Shape aSubShape = anIndices.FindKey(myInters[i*2+j]); TopoDS_Shape aSubShape = anIndices.FindKey(getInters()[i*2+j]);
QString aType = GEOMBase::GetShapeTypeString(aSubShape); QString aType = GEOMBase::GetShapeTypeString(aSubShape);
myShapeList->addItem(QString("%1_%2").arg(aType).arg(myInters[i*2+j])); getShapeList()->addItem(QString("%1_%2").arg(aType).arg(getInters()[i*2+j]));
myShapeList->item(myShapeList->count()-1)->setData(Qt::UserRole, myInters[i*2+j]); getShapeList()->item(getShapeList()->count()-1)->setData(Qt::UserRole, getInters()[i*2+j]);
} }
} }
} }
@ -480,7 +652,7 @@ void MeasureGUI_CheckSelfIntersectionsDlg::onSubShapesListSelectionChanged()
erasePreview(); erasePreview();
// Selected IDs // Selected IDs
QList<QListWidgetItem*> selected = myShapeList->selectedItems(); QList<QListWidgetItem*> selected = getShapeList()->selectedItems();
QList<int> aIds; QList<int> aIds;
foreach(QListWidgetItem* item, selected) { foreach(QListWidgetItem* item, selected) {
int idx = item->data(Qt::UserRole).toInt(); int idx = item->data(Qt::UserRole).toInt();
@ -492,7 +664,7 @@ void MeasureGUI_CheckSelfIntersectionsDlg::onSubShapesListSelectionChanged()
TopoDS_Shape aSelShape; TopoDS_Shape aSelShape;
TopoDS_Shape aSubShape; TopoDS_Shape aSubShape;
TopTools_IndexedMapOfShape anIndices; TopTools_IndexedMapOfShape anIndices;
if (!myObj->_is_nil() && GEOMBase::GetShape(myObj, aSelShape)) { if (!getObj()->_is_nil() && GEOMBase::GetShape(getObj().get(), aSelShape)) {
TopExp::MapShapes(aSelShape, anIndices); TopExp::MapShapes(aSelShape, anIndices);
getDisplayer()->SetColor(Quantity_NOC_RED); getDisplayer()->SetColor(Quantity_NOC_RED);
getDisplayer()->SetWidth(3); getDisplayer()->SetWidth(3);
@ -500,11 +672,11 @@ void MeasureGUI_CheckSelfIntersectionsDlg::onSubShapesListSelectionChanged()
foreach(int idx, aIds) { foreach(int idx, aIds) {
aSubShape = anIndices.FindKey(idx); aSubShape = anIndices.FindKey(idx);
try { try {
SALOME_Prs* aPrs = !aSubShape.IsNull() ? getDisplayer()->BuildPrs(aSubShape) : 0; SALOME_Prs* aPrs = !aSubShape.IsNull() ? getDisplayer()->BuildPrs(aSubShape) : 0;
if (aPrs) displayPreview(aPrs, true); if (aPrs) displayPreview(aPrs, true);
} }
catch (const SALOME::SALOME_Exception& e) { catch (const SALOME::SALOME_Exception& e) {
SalomeApp_Tools::QtCatchCorbaException(e); SalomeApp_Tools::QtCatchCorbaException(e);
} }
} }
} }
@ -526,15 +698,15 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::execute(ObjectList& objects)
TColStd_IndexedMapOfInteger aMapIndex; TColStd_IndexedMapOfInteger aMapIndex;
QList<int> pairs; QList<int> pairs;
int nbSelected = myInteList->selectedItems().size(); int nbSelected = getInteList()->selectedItems().size();
// Collect the map of indices // Collect the map of indices
for (int i = 0; i < myInteList->count(); i++) { for (int i = 0; i < getInteList()->count(); i++) {
if ( nbSelected < 1 || myInteList->item(i)->isSelected() ) { if ( nbSelected < 1 || getInteList()->item(i)->isSelected() ) {
aMapIndex.Add(myInters[i*2]); aMapIndex.Add(getInters()[i*2]);
aMapIndex.Add(myInters[i*2 + 1]); aMapIndex.Add(getInters()[i*2 + 1]);
pairs << myInters[i*2]; pairs << getInters()[i*2];
pairs << myInters[i*2 + 1]; pairs << getInters()[i*2 + 1];
} }
} }
@ -547,7 +719,7 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::execute(ObjectList& objects)
for (int i = 1; i <= aMapIndex.Extent(); i++) for (int i = 1; i <= aMapIndex.Extent(); i++)
anArray[i-1] = aMapIndex.FindKey(i); anArray[i-1] = aMapIndex.FindKey(i);
GEOM::ListOfGO_var aList = shapesOper->MakeSubShapes(myObj, anArray); GEOM::ListOfGO_var aList = shapesOper->MakeSubShapes(getObj().get(), anArray);
// Make compounds // Make compounds
for (int i = 0; i < pairs.count()/2; i++) { for (int i = 0; i < pairs.count()/2; i++) {
@ -562,6 +734,27 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::execute(ObjectList& objects)
return true; return true;
} }
//=================================================================================
// function : getDeflection
// purpose :
//=================================================================================
float MeasureGUI_CheckSelfIntersectionsDlg::getDeflection()
{
return (float)myDeflection->value();
}
//=================================================================================
// function : getTolerance
// purpose :
//=================================================================================
double MeasureGUI_CheckSelfIntersectionsDlg::getTolerance()
{
double aVal = myTolerance->value();
if (!myDetGaps->isChecked() || aVal < 0.0)
return 0.0;
return aVal;
}
//================================================================ //================================================================
// Function : getFather // Function : getFather
// Purpose : Get father object for object to be added in study // Purpose : Get father object for object to be added in study
@ -570,5 +763,54 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::execute(ObjectList& objects)
GEOM::GEOM_Object_ptr MeasureGUI_CheckSelfIntersectionsDlg::getFather GEOM::GEOM_Object_ptr MeasureGUI_CheckSelfIntersectionsDlg::getFather
(GEOM::GEOM_Object_ptr) (GEOM::GEOM_Object_ptr)
{ {
return myObj; return getObj().get();
}
//=================================================================================
// function : getSourceObjects
// purpose : virtual method to get source objects
//=================================================================================
QList<GEOM::GeomObjPtr> MeasureGUI_CheckSelfIntersectionsDlg::getSourceObjects()
{
QList<GEOM::GeomObjPtr> res;
res << getObj();
return res;
}
//=================================================================================
// GETTERS
//=================================================================================
QTextBrowser* MeasureGUI_CheckSelfIntersectionsDlg::getTextView()
{
return ( getConstructorId() == 0 ? myTextView1 : myTextView2 );
}
QListWidget* MeasureGUI_CheckSelfIntersectionsDlg::getInteList()
{
return ( getConstructorId() == 0 ? myInteList1 : myInteList2 );
}
QListWidget* MeasureGUI_CheckSelfIntersectionsDlg::getShapeList()
{
return ( getConstructorId() == 0 ? myShapeList1 : myShapeList2 );
}
QPushButton* MeasureGUI_CheckSelfIntersectionsDlg::getComputeButton()
{
return ( getConstructorId() == 0 ? myComputeButton1 : myComputeButton2 );
}
QLineEdit* MeasureGUI_CheckSelfIntersectionsDlg::getEditObjName()
{
return ( getConstructorId() == 0 ? myEditObjName1 : myEditObjName2 );
}
GEOM::GeomObjPtr MeasureGUI_CheckSelfIntersectionsDlg::getObj()
{
return ( getConstructorId() == 0 ? myObj1 : myObj2 );
}
GEOM::ListOfLong_var MeasureGUI_CheckSelfIntersectionsDlg::getInters()
{
return ( getConstructorId() == 0 ? myInters1 : myInters2 );
} }

View File

@ -54,6 +54,7 @@ protected:
virtual bool execute(ObjectList &); virtual bool execute(ObjectList &);
virtual bool extractPrefix() const; virtual bool extractPrefix() const;
virtual GEOM::GEOM_Object_ptr getFather (GEOM::GEOM_Object_ptr); virtual GEOM::GEOM_Object_ptr getFather (GEOM::GEOM_Object_ptr);
virtual QList<GEOM::GeomObjPtr> getSourceObjects();
private slots: private slots:
@ -67,6 +68,9 @@ private slots:
void DeactivateActiveDialog(); void DeactivateActiveDialog();
void SelectionIntoArgument(); void SelectionIntoArgument();
void SetEditCurrentArgument(); void SetEditCurrentArgument();
void ConstructorsClicked (int);
void OnGaps(bool);
private: private:
@ -76,18 +80,46 @@ private:
bool findSelfIntersections bool findSelfIntersections
(bool &HasSelfInte, (bool &HasSelfInte,
QString &theErrMsg); QString &theErrMsg);
float getDeflection();
double getTolerance();
// Getters
QTextBrowser* getTextView();
QListWidget* getInteList();
QListWidget* getShapeList();
QPushButton* getComputeButton();
QLineEdit* getEditObjName();
GEOM::GeomObjPtr getObj();
GEOM::ListOfLong_var getInters();
private: private:
int myCurrConstrId;
QTextBrowser *myTextView; // simple
QPushButton *mySelButton; QPushButton *myComputeButton1;
QLineEdit *myEditObjName; QGroupBox *mySimpleGrp;
QTextBrowser *myTextView1;
QPushButton *mySelButton1;
QLineEdit *myEditObjName1;
QComboBox *myLevelBox; QComboBox *myLevelBox;
QPushButton *myComputeButton; QListWidget *myInteList1;
QListWidget *myInteList; QListWidget *myShapeList1;
QListWidget *myShapeList; GEOM::GeomObjPtr myObj1;
GEOM::GEOM_Object_var myObj; GEOM::ListOfLong_var myInters1;
GEOM::ListOfLong_var myInters; // fast
QPushButton *myComputeButton2;
QGroupBox *myFastGrp;
QTextBrowser *myTextView2;
QPushButton *mySelButton2;
QLineEdit *myEditObjName2;
QCheckBox *myDetGaps;
SalomeApp_DoubleSpinBox *myTolerance;
SalomeApp_DoubleSpinBox *myDeflection;
QListWidget *myInteList2;
QListWidget *myShapeList2;
GEOM::GeomObjPtr myObj2;
GEOM::ListOfLong_var myInters2;
GEOM::GEOM_IShapesOperations_var myShapesOper;
}; };
#endif // MEASUREGUI_CHECKSELFINTERDLG_H #endif // MEASUREGUI_CHECKSELFINTERDLG_H