diff --git a/doc/salome/gui/GEOM/images/measures11.png b/doc/salome/gui/GEOM/images/measures11.png new file mode 100644 index 000000000..85af6f187 Binary files /dev/null and b/doc/salome/gui/GEOM/images/measures11.png differ diff --git a/doc/salome/gui/GEOM/input/tui_measurement_tools.doc b/doc/salome/gui/GEOM/input/tui_measurement_tools.doc index f8dbcd38c..c36edc455 100644 --- a/doc/salome/gui/GEOM/input/tui_measurement_tools.doc +++ b/doc/salome/gui/GEOM/input/tui_measurement_tools.doc @@ -385,6 +385,20 @@ else: print "\nBox is valid" \endcode +

Detect Self-intersections

+ +\code +import geompy + +# create a box +box = geompy.MakeBoxDXDYDZ(100,30,100) +IsValid = geompy.CheckSelfIntersections(box) +if IsValid == 0: + raise RuntimeError, "Box with self-intersections created" +else: + print "\nBox is valid" +\endcode +

Check Compound of Blocks

\code diff --git a/doc/salome/gui/GEOM/input/using_measurement_tools.doc b/doc/salome/gui/GEOM/input/using_measurement_tools.doc index 13765941c..489c22862 100644 --- a/doc/salome/gui/GEOM/input/using_measurement_tools.doc +++ b/doc/salome/gui/GEOM/input/using_measurement_tools.doc @@ -1,59 +1,60 @@ -/*! - -\page using_measurement_tools_page Using measurement tools - -\n Measurement tools in GEOM are necessary for getting different data -concerning created or imported geometrical objects. They are: - - + +\n Our TUI Scripts show how to use +\ref tui_measurement_tools_page "Measurement Tools" with TUI +commands. + +\n To use measurement tools: +\par +In the Main menu select \b Measures submenu. + +\anchor point_coord_anchor +

Point coordinates

+ +\n Returns the coordinates of a point. + +\n Result: Point coordinates (X, Y, Z) in 3D space in the form of Python Tuple. +\n TUI Command: geompy.PointCoordinates(Point), +where \em Point is a point whose coordinates are inquired. + +\image html measures1.png + +\anchor basic_prop_anchor +

Basic properties

+ +\n Returns the properties (Length, Surface & Volume) for the selected +geometrical object. + +\n Result: Display Length, Surface & Volume in the form of +Python Tuple. +\n TUI Command: geompy.BasicProperties(Shape), where +\em Shape is a shape whose properties are inquired. + +\image html neo-basicprop.png \anchor center_mass_anchor

Center of mass

@@ -99,44 +100,44 @@ returned. \anchor normale_anchor

Normal to a Face

-\n Calculates the normal vector to the selected \b Face. The \b Point -is a point of the \b Face, where the Normal should be calculated. - -\image html normaletoface.png - -\anchor boundaries_anchor -

Check Free Boundaries

- -\n Detects and highlights wires and edges that are not shared between -two faces and are considered a shape's boundary. - -\n TUI Command: (NoError, ClosedWires, OpenWires) = -geompy.GetFreeBoundary(Shape), where \em Shape is a shape to be -checked, \em NoError is false if an error occurred while checking free -boundaries, \em ClosedWires is a list of closed free boundary wires, -\em OpenWires is a list of open free boundary wires. - -\image html repair9.png - -\anchor faces_anchor -

Check Free Faces

- -\n Highlights all free faces of a given shape. A free -face is a face which is not shared between two objects of the shape. - -\n \b NOTE: This functionality works only in VTK viewer. - -\n \b Result: a list of IDs of all free faces, containing in the shape. -\n TUI Command: GetFreeFacesIDs(Shape), where \em Shape is -a shape to be checked. - -\image html repair10.png - -\anchor bounding_box_anchor -

Bounding box

- -Returns the dimensions of the bounding box for the selected -geometrical object. +\n Calculates the normal vector to the selected \b Face. The \b Point +is a point of the \b Face, where the Normal should be calculated. + +\image html normaletoface.png + +\anchor boundaries_anchor +

Check Free Boundaries

+ +\n Detects and highlights wires and edges that are not shared between +two faces and are considered a shape's boundary. + +\n TUI Command: (NoError, ClosedWires, OpenWires) = +geompy.GetFreeBoundary(Shape), where \em Shape is a shape to be +checked, \em NoError is false if an error occurred while checking free +boundaries, \em ClosedWires is a list of closed free boundary wires, +\em OpenWires is a list of open free boundary wires. + +\image html repair9.png + +\anchor faces_anchor +

Check Free Faces

+ +\n Highlights all free faces of a given shape. A free +face is a face which is not shared between two objects of the shape. + +\n \b NOTE: This functionality works only in VTK viewer. + +\n \b Result: a list of IDs of all free faces, containing in the shape. +\n TUI Command: GetFreeFacesIDs(Shape), where \em Shape is +a shape to be checked. + +\image html repair10.png + +\anchor bounding_box_anchor +

Bounding box

+ +Returns the dimensions of the bounding box for the selected +geometrical object. \b NOTE: In order to take into account any possible distortion of a shape that affects the resulting bounding box, the algorithm enlarges @@ -145,114 +146,127 @@ faces (by iterating through all faces of a shape). This functionallity is implemented in such a way in order to have satisfactory performance. -Result: Displays the dimensions of the bounding box of a -geometrical object in the form of Python Tuple (Xmin, Xmax, Ymin, -Ymax, Zmin, Zmax). -\n TUI Command: geompy.BoundingBox(Shape), where \em Shape -is a shape for which a bounding box is computed. - -\image html measures5.png - -\anchor min_distance_anchor -

Min. distance

- -\n Returns the minimum distance between two geometrical objects and -the coordinates of the vector of distance and shows the vector in the viewer. - -\n TUI Command: geompy.MinDistance(Shape1, Shape2), -where \em Shape1 and \em Shape2 are shapes between which the minimal -distance is computed. - -\image html distance.png - -\anchor angle_anchor -

Angle

- -\n Returns the angle between two lines or linear edges in degrees -\n TUI Command: geompy.GetAngle(shape1, shape2), where -Shape1 and Shape2 are shapes between which the angle is computed. -Another TUI command is geompy.GetAngleRadians(shape1,shape2), -which returns the value of angle in radians. - -\image html angle.png - -\anchor tolerance_anchor -

Tolerance

- -\n Returns the maximum and the minimum tolerance for the selected -geometrical object. - -\n Result: Displays the tolerance values (FaceMinTol, -FaceMaxTol, EgdeMinTol, EgdeMaxTol, VertexMinTol, VertexMaxTol). -\n TUI Command: geompy.Tolerance(Shape), where \em Shape -is a shape for which minimal and maximal tolerances are returned. - -\image html new-tolerance.png - -\anchor whatis_anchor -

WhatIs

- -\n General information about the selected geometrical object is the -list of types and quantities of all topological entities, composing -the shape. - -\n TUI Command: geompy.WhatIs(Shape), where \em Shape is a -shape from which a description is returned. - -\image html measures8.png - -\n Kind of Shape field characterises the -whole shape. If there is no additional information available for the -shape, Basic Properties button will be disabled, otherwise it -will show a dialog with information about -dimensions, position, orientation and other parameters of the shape. - -\n TUI Command: geompy.KindOfShape(Shape), where \em Shape is a -shape from which a description is returned. - -\image html measures8a.png - -\anchor check_anchor -

Check

- -\n Checks the topology of the selected geometrical object and returns -True if it is valid. Check also geometry checkbox allows to test the -geometry as well. - -\n Result: Boolean. -\n TUI Command: geompy.CheckShape(theShape, theIsCheckGeom = 0), -where \em theShape is the shape checked for validity. - -\image html measures9.png - -\anchor check_compound_anchor -

Check compound of blocks

- -\n Checks whether a shape is a compound of glued blocks. To be -considered as a compound of blocks, the given shape must satisfy the -following conditions: - - -\n Informs of the following possible errors: - - -\n Result: Boolean; highlight in the viewer. -\n TUI Command: -geompy.CheckCompoundOfBlocks(Compound). Checks if the shape -is a valid compound of blocks. If it is true, then the validity flag -is returned, and encountered errors are printed in the python console. - -\image html measures10.png - -*/ - +Result: Displays the dimensions of the bounding box of a +geometrical object in the form of Python Tuple (Xmin, Xmax, Ymin, +Ymax, Zmin, Zmax). +\n TUI Command: geompy.BoundingBox(Shape), where \em Shape +is a shape for which a bounding box is computed. + +\image html measures5.png + +\anchor min_distance_anchor +

Min. distance

+ +\n Returns the minimum distance between two geometrical objects and +the coordinates of the vector of distance and shows the vector in the viewer. + +\n TUI Command: geompy.MinDistance(Shape1, Shape2), +where \em Shape1 and \em Shape2 are shapes between which the minimal +distance is computed. + +\image html distance.png + +\anchor angle_anchor +

Angle

+ +\n Returns the angle between two lines or linear edges in degrees +\n TUI Command: geompy.GetAngle(shape1, shape2), where +Shape1 and Shape2 are shapes between which the angle is computed. +Another TUI command is geompy.GetAngleRadians(shape1,shape2), +which returns the value of angle in radians. + +\image html angle.png + +\anchor tolerance_anchor +

Tolerance

+ +\n Returns the maximum and the minimum tolerance for the selected +geometrical object. + +\n Result: Displays the tolerance values (FaceMinTol, +FaceMaxTol, EgdeMinTol, EgdeMaxTol, VertexMinTol, VertexMaxTol). +\n TUI Command: geompy.Tolerance(Shape), where \em Shape +is a shape for which minimal and maximal tolerances are returned. + +\image html new-tolerance.png + +\anchor whatis_anchor +

WhatIs

+ +\n General information about the selected geometrical object is the +list of types and quantities of all topological entities, composing +the shape. + +\n TUI Command: geompy.WhatIs(Shape), where \em Shape is a +shape from which a description is returned. + +\image html measures8.png + +\n Kind of Shape field characterises the +whole shape. If there is no additional information available for the +shape, Basic Properties button will be disabled, otherwise it +will show a dialog with information about +dimensions, position, orientation and other parameters of the shape. + +\n TUI Command: geompy.KindOfShape(Shape), where \em Shape is a +shape from which a description is returned. + +\image html measures8a.png + +\anchor check_anchor +

Check

+ +\n Checks the topology of the selected geometrical object and returns +True if it is valid. Check also geometry checkbox allows to test the +geometry as well. + +\n Result: Boolean. +\n TUI Command: geompy.CheckShape(theShape, theIsCheckGeom = 0), +where \em theShape is the shape checked for validity. + +\image html measures9.png + +\anchor check_compound_anchor +

Check compound of blocks

+ +\n Checks whether a shape is a compound of glued blocks. To be +considered as a compound of blocks, the given shape must satisfy the +following conditions: + + +\n Informs of the following possible errors: + + +\n Result: Boolean; highlight in the viewer. +\n TUI Command: +geompy.CheckCompoundOfBlocks(Compound). Checks if the shape +is a valid compound of blocks. If it is true, then the validity flag +is returned, and encountered errors are printed in the python console. + +\image html measures10.png + +\anchor check_self_intersections_anchor +

Detect Self-intersections

+ +\n Checks the topology of the selected shape to detect self-intersections. + Returns True if there are no self-intersections. Reports pairs of + intersected sub shapes, if there are any. + +\n Result: Boolean. +\n TUI Command: geompy.CheckSelfIntersections(theShape), +where \em theShape is the shape checked for validity. + +\image html measures11.png + +*/ + diff --git a/idl/GEOM_Gen.idl b/idl/GEOM_Gen.idl index e1ce70642..136310506 100644 --- a/idl/GEOM_Gen.idl +++ b/idl/GEOM_Gen.idl @@ -3287,6 +3287,15 @@ module GEOM boolean CheckShapeWithGeometry (in GEOM_Object theShape, out string theDescription); + /*! + * Check a topology of the given shape on self-intersections presence. + * \param theShape Shape to check validity of. + * \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 CheckSelfIntersections (in GEOM_Object theShape, + out ListOfLong theIntersections); + /*! * Check if the given shape can be an argument for MakeSolid operation * \param theShape Shape to be described. diff --git a/resources/Makefile.am b/resources/Makefile.am index 6313fd6c7..bb376f509 100644 --- a/resources/Makefile.am +++ b/resources/Makefile.am @@ -15,13 +15,12 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# # -* Makefile *- # Author : Patrick GOLDBRONN (CEA) # Date : 28/06/2001 # Modified by : Alexander BORODIN (OCN) - autotools usage -# + include $(top_srcdir)/adm_local/unix/make_common_starter.am dist_salomeres_DATA = \ @@ -221,6 +220,7 @@ group_new.png \ group_edit.png \ glue.png \ check_blocks_compound.png \ +check_self_intersections.png \ free_faces.png \ propagate.png \ redo.png \ diff --git a/resources/check_self_intersections.png b/resources/check_self_intersections.png new file mode 100644 index 000000000..0330d6a48 Binary files /dev/null and b/resources/check_self_intersections.png differ diff --git a/src/GEOMGUI/GEOM_images.ts b/src/GEOMGUI/GEOM_images.ts index 2fc4d646c..690fbf9b4 100644 --- a/src/GEOMGUI/GEOM_images.ts +++ b/src/GEOMGUI/GEOM_images.ts @@ -159,6 +159,10 @@ ICON_DLG_CHECK_COMPOUND_OF_BLOCKS check_blocks_compound.png + + ICON_DLG_CHECK_SELF_INTERSECTIONS + check_self_intersections.png + ICON_DLG_CIRCLE_PNTS circle3points.png @@ -719,6 +723,10 @@ ICO_CHECK_COMPOUND check_blocks_compound.png + + ICO_CHECK_SELF_INTERSECTIONS + check_self_intersections.png + ICO_CHECK_FREE_BNDS free_bound.png diff --git a/src/GEOMGUI/GEOM_msg_en.ts b/src/GEOMGUI/GEOM_msg_en.ts index b55baeb18..33f6a4986 100644 --- a/src/GEOMGUI/GEOM_msg_en.ts +++ b/src/GEOMGUI/GEOM_msg_en.ts @@ -357,6 +357,22 @@ Please, select face, shell or solid and try again GEOM_CHECK_TITLE Check Shape Information + + GEOM_CHECK_SELF_INTERSECTIONS + Detect Self-intersections + + + GEOM_CHECK_SELF_INTERSECTIONS_FAILED + Detection of self-intersections failed + + + GEOM_NO_SELF_INTERSECTIONS + There are no self-intersections in the shape + + + GEOM_SELF_INTERSECTIONS_FOUND + Some self-intersections detected + GEOM_CIRCLE Circle @@ -2213,6 +2229,10 @@ Please, select face, shell or solid and try again MEN_CHECK_COMPOUND Check Compound of Blocks + + MEN_CHECK_SELF_INTERSECTIONS + Detect Self-intersections + MEN_CHECK_FREE_BNDS Check Free Boundaries @@ -2905,6 +2925,10 @@ Please, select face, shell or solid and try again STB_CHECK_COMPOUND Check compound of blocks + + STB_CHECK_SELF_INTERSECTIONS + Detect Self-intersections + STB_CHECK_FREE_BNDS Check free boundaries @@ -3465,6 +3489,10 @@ Please, select face, shell or solid and try again TOP_CHECK_COMPOUND Check compound of blocks + + TOP_CHECK_SELF_INTERSECTIONS + Detect Self-intersections + TOP_CHECK_FREE_BNDS Check free boundaries diff --git a/src/GEOMGUI/GeometryGUI.cxx b/src/GEOMGUI/GeometryGUI.cxx index 59670b4cc..60d773472 100644 --- a/src/GEOMGUI/GeometryGUI.cxx +++ b/src/GEOMGUI/GeometryGUI.cxx @@ -535,6 +535,7 @@ void GeometryGUI::OnGUIEvent( int id ) case GEOMOp::OpCheckShape: // MENU MEASURE - CHECK case GEOMOp::OpCheckCompound: // MENU MEASURE - CHECK COMPOUND OF BLOCKS case GEOMOp::OpPointCoordinates: // MENU MEASURE - POINT COORDINATES + case GEOMOp::OpCheckSelfInters: // MENU MEASURE - CHECK SELF INTERSECTIONS libName = "MeasureGUI"; break; case GEOMOp::OpGroupCreate: // MENU GROUP - CREATE @@ -796,6 +797,7 @@ void GeometryGUI::initialize( CAM_Application* app ) createGeomAction( GEOMOp::OpWhatIs, "WHAT_IS" ); createGeomAction( GEOMOp::OpCheckShape, "CHECK" ); createGeomAction( GEOMOp::OpCheckCompound, "CHECK_COMPOUND" ); + createGeomAction( GEOMOp::OpCheckSelfInters, "CHECK_SELF_INTERSECTIONS" ); #ifdef _DEBUG_ // PAL16821 createGeomAction( GEOMOp::OpCheckGeom, "CHECK_GEOMETRY" ); @@ -1007,12 +1009,13 @@ void GeometryGUI::initialize( CAM_Application* app ) createMenu( GEOMOp::OpMinDistance, dimId, -1 ); createMenu( GEOMOp::OpAngle, dimId, -1 ); - createMenu( separator(), measurId, -1 ); - createMenu( GEOMOp::OpTolerance, measurId, -1 ); - createMenu( separator(), measurId, -1 ); - createMenu( GEOMOp::OpWhatIs, measurId, -1 ); - createMenu( GEOMOp::OpCheckShape, measurId, -1 ); - createMenu( GEOMOp::OpCheckCompound, measurId, -1 ); + createMenu( separator(), measurId, -1 ); + createMenu( GEOMOp::OpTolerance, measurId, -1 ); + createMenu( separator(), measurId, -1 ); + createMenu( GEOMOp::OpWhatIs, measurId, -1 ); + createMenu( GEOMOp::OpCheckShape, measurId, -1 ); + createMenu( GEOMOp::OpCheckCompound, measurId, -1 ); + createMenu( GEOMOp::OpCheckSelfInters, measurId, -1 ); #ifdef _DEBUG_ // PAL16821 int toolsId = createMenu( tr( "MEN_TOOLS" ), -1, -1, 50 ); @@ -1140,6 +1143,7 @@ void GeometryGUI::initialize( CAM_Application* app ) createTool( GEOMOp::OpWhatIs, measureTbId ); createTool( GEOMOp::OpCheckShape, measureTbId ); createTool( GEOMOp::OpCheckCompound, measureTbId ); + createTool( GEOMOp::OpCheckSelfInters, measureTbId ); int advancedTbId = createTool( tr( "TOOL_ADVANCED" ) ); createTool( GEOMOp::OpPipeTShape, advancedTbId ); diff --git a/src/GEOMGUI/GeometryGUI_Operations.h b/src/GEOMGUI/GeometryGUI_Operations.h index cabc0e9f3..1731c1772 100644 --- a/src/GEOMGUI/GeometryGUI_Operations.h +++ b/src/GEOMGUI/GeometryGUI_Operations.h @@ -160,6 +160,7 @@ namespace GEOMOp { OpCheckShape = 5009, // MENU MEASURES - CHECK OpCheckCompound = 5010, // MENU MEASURES - CHECK COMPOUND OF BLOCKS OpPointCoordinates = 5011, // MENU MEASURES - POINT COORDINATES + OpCheckSelfInters = 5012, // MENU MEASURES - CHECK SELF INTERSECTIONS // GroupGUI ------------------//-------------------------------- OpGroupCreate = 6000, // MENU GROUP - CREATE OpGroupEdit = 6001, // MENU GROUP - EDIT diff --git a/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx b/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx index 9dbdcf6be..4a24fd2c4 100644 --- a/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx @@ -34,6 +34,15 @@ #include #include +#include + +#include +#include +#include +#include +#include +#include + #include #include @@ -1310,6 +1319,88 @@ bool GEOMImpl_IMeasureOperations::CheckShape (Handle(GEOM_Object) theShape, return isValid; } +//============================================================================= +/*! + * CheckSelfIntersections + */ +//============================================================================= +bool GEOMImpl_IMeasureOperations::CheckSelfIntersections + (Handle(GEOM_Object) theShape, + Handle(TColStd_HSequenceOfInteger)& theIntersections) +{ + SetErrorCode(KO); + bool isGood = false; + + if (theIntersections.IsNull()) + theIntersections = new TColStd_HSequenceOfInteger; + else + theIntersections->Clear(); + + if (theShape.IsNull()) + return isGood; + + Handle(GEOM_Function) aRefShape = theShape->GetLastFunction(); + if (aRefShape.IsNull()) return isGood; + + TopoDS_Shape aShape = aRefShape->GetValue(); + if (aShape.IsNull()) return isGood; + + // 0. Prepare data + BRep_Builder aBB; + TopoDS_Compound aCS; + TopoDS_Shape aScopy; + NMTDS_Tools::CopyShape(aShape, aScopy); + + // Map sub-shapes and their indices + TopTools_IndexedMapOfShape anIndices; + TopExp::MapShapes(aScopy, anIndices); + + aBB.MakeCompound(aCS); + aBB.Add(aCS, aScopy); + + NMTTools_CheckerSI aCSI; // checker of self-interferences + aCSI.SetCompositeShape(aCS); + + // 1. Launch the checker + aCSI.Perform(); + Standard_Integer iErr = aCSI.StopStatus(); + if (iErr) { + return false; // Error + } + + isGood = true; + + // 2. Take the shapes from DS + const NMTDS_ShapesDataStructure& aDS = *(aCSI.DS()); + Standard_Integer aNbS = aDS.NumberOfShapesOfTheObject(); + + // 3. Get the pairs of interfered shapes + NMTDS_PInterfPool pIP = aCSI.IP(); + const NMTDS_ListOfPassKeyBoolean& aLPKB = pIP->Get(); + + Standard_Integer n1, n2; + NMTDS_ListIteratorOfListOfPassKeyBoolean aIt; + + aIt.Initialize(aLPKB); + for (; aIt.More(); aIt.Next()) { + const NMTDS_PassKeyBoolean& aPKB = aIt.Value(); + aPKB.Ids(n1, n2); + + if (n1 > aNbS || n2 > aNbS) + return false; // Error + + const TopoDS_Shape& aS1 = aDS.Shape(n1); + const TopoDS_Shape& aS2 = aDS.Shape(n2); + + theIntersections->Append(anIndices.FindIndex(aS1)); + theIntersections->Append(anIndices.FindIndex(aS2)); + isGood = false; + } + + SetErrorCode(OK); + return isGood; +} + //============================================================================= /*! * IsGoodForSolid diff --git a/src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx b/src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx index 6f99d77b9..5a3966ddc 100644 --- a/src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx +++ b/src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx @@ -18,7 +18,6 @@ // 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_IMeasureOperations_HXX_ #define _GEOMImpl_IMeasureOperations_HXX_ @@ -127,6 +126,9 @@ class GEOMImpl_IMeasureOperations : public GEOM_IOperations { const Standard_Boolean theIsCheckGeom, TCollection_AsciiString& theDump); + Standard_EXPORT bool CheckSelfIntersections (Handle(GEOM_Object) theShape, + Handle(TColStd_HSequenceOfInteger)& theIntersections); + Standard_EXPORT TCollection_AsciiString IsGoodForSolid (Handle(GEOM_Object) theShape); Standard_EXPORT TCollection_AsciiString WhatIs (Handle(GEOM_Object) theShape); diff --git a/src/GEOMImpl/Makefile.am b/src/GEOMImpl/Makefile.am index cfe3b0f1c..a0ec6a7fd 100644 --- a/src/GEOMImpl/Makefile.am +++ b/src/GEOMImpl/Makefile.am @@ -241,6 +241,7 @@ libGEOMimpl_la_CPPFLAGS = \ $(BOOST_CPPFLAGS) \ $(PYTHON_INCLUDES) \ -I$(srcdir)/../ShHealOper \ + -I$(srcdir)/../NMTDS \ -I$(srcdir)/../NMTTools \ -I$(srcdir)/../GEOM \ -I$(srcdir)/../GEOMAlgo \ diff --git a/src/GEOM_I/GEOM_IMeasureOperations_i.cc b/src/GEOM_I/GEOM_IMeasureOperations_i.cc index 800a072c2..80126995a 100644 --- a/src/GEOM_I/GEOM_IMeasureOperations_i.cc +++ b/src/GEOM_I/GEOM_IMeasureOperations_i.cc @@ -18,7 +18,6 @@ // 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 @@ -367,6 +366,45 @@ CORBA::Boolean GEOM_IMeasureOperations_i::CheckShapeWithGeometry (GEOM::GEOM_Obj return 0; } +//============================================================================= +/*! + * CheckSelfIntersections + */ +//============================================================================= +CORBA::Boolean GEOM_IMeasureOperations_i::CheckSelfIntersections (GEOM::GEOM_Object_ptr theShape, + 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()->CheckSelfIntersections(aShape, 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; +} + //============================================================================= /*! * IsGoodForSolid diff --git a/src/GEOM_I/GEOM_IMeasureOperations_i.hh b/src/GEOM_I/GEOM_IMeasureOperations_i.hh index bd9d1b7ce..344a9def0 100644 --- a/src/GEOM_I/GEOM_IMeasureOperations_i.hh +++ b/src/GEOM_I/GEOM_IMeasureOperations_i.hh @@ -18,7 +18,6 @@ // 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 _GEOM_IMeasureOperations_i_HeaderFile #define _GEOM_IMeasureOperations_i_HeaderFile @@ -86,6 +85,9 @@ class GEOM_I_EXPORT GEOM_IMeasureOperations_i : CORBA::Boolean CheckShapeWithGeometry (GEOM::GEOM_Object_ptr theShape, CORBA::String_out theDescription); + CORBA::Boolean CheckSelfIntersections (GEOM::GEOM_Object_ptr theShape, + GEOM::ListOfLong_out theIntersections); + char* IsGoodForSolid (GEOM::GEOM_Object_ptr theShape); char* WhatIs (GEOM::GEOM_Object_ptr theShape); diff --git a/src/GEOM_SWIG/GEOM_TestMeasures.py b/src/GEOM_SWIG/GEOM_TestMeasures.py index e153beb8b..14a3f5743 100644 --- a/src/GEOM_SWIG/GEOM_TestMeasures.py +++ b/src/GEOM_SWIG/GEOM_TestMeasures.py @@ -19,7 +19,6 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# def TestMeasureOperations (geompy, math): @@ -47,6 +46,14 @@ def TestMeasureOperations (geompy, math): else: print "\nBox is valid" + ####### Detect Self-intersections ####### + + [Face_1,Face_2] = geompy.SubShapes(box, [33, 23]) + Translation_1 = geompy.MakeTranslation(Face_1, 5, -15, -40) + Compound_1 = geompy.MakeCompound([Face_2, Translation_1]) + if geompy.CheckSelfIntersections(Compound_1) == True: + raise RuntimeError, "Existing self-intersection is not detected" + ####### WhatIs ####### Descr = geompy.WhatIs(box) diff --git a/src/GEOM_SWIG/geompyDC.py b/src/GEOM_SWIG/geompyDC.py index 1e0903119..5936e3b29 100644 --- a/src/GEOM_SWIG/geompyDC.py +++ b/src/GEOM_SWIG/geompyDC.py @@ -3755,6 +3755,17 @@ class geompyDC(GEOM._objref_GEOM_Gen): print Status return IsValid + ## Detect self-intersections in the given shape. + # @param theShape Shape to check. + # @return TRUE, if the shape contains no self-intersections. + # + # @ref tui_measurement_tools_page "Example" + def CheckSelfIntersections (self, theShape): + # Example: see GEOM_TestMeasures.py + (IsValid, Pairs) = self.MeasuOp.CheckSelfIntersections(theShape) + RaiseIfFailed("CheckSelfIntersections", self.MeasuOp) + return IsValid + ## Get position (LCS) of theShape. # # Origin of the LCS is situated at the shape's center of mass. diff --git a/src/MeasureGUI/Makefile.am b/src/MeasureGUI/Makefile.am index f14cc4a88..766128d86 100644 --- a/src/MeasureGUI/Makefile.am +++ b/src/MeasureGUI/Makefile.am @@ -15,13 +15,12 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# # GEOM MEASUREGUI : # File : Makefile.am # Author : Alexander BORODIN, Open CASCADE S.A.S. (alexander.borodin@opencascade.com) # Package : MeasureGUI -# + include $(top_srcdir)/adm_local/unix/make_common_starter.am # header files @@ -40,6 +39,7 @@ salomeinclude_HEADERS = \ MeasureGUI_WhatisDlg.h \ MeasureGUI_CheckShapeDlg.h \ MeasureGUI_CheckCompoundOfBlocksDlg.h \ + MeasureGUI_CheckSelfIntersectionsDlg.h \ MeasureGUI_PointDlg.h # Libraries targets @@ -59,7 +59,8 @@ dist_libMeasureGUI_la_SOURCES = \ MeasureGUI_MaxToleranceDlg.cxx \ MeasureGUI_WhatisDlg.cxx \ MeasureGUI_CheckShapeDlg.cxx \ - MeasureGUI_CheckCompoundOfBlocksDlg.cxx \ + MeasureGUI_CheckCompoundOfBlocksDlg.cxx \ + MeasureGUI_CheckSelfIntersectionsDlg.cxx \ MeasureGUI_PointDlg.cxx MOC_FILES = \ @@ -76,6 +77,7 @@ MOC_FILES = \ MeasureGUI_WhatisDlg_moc.cxx \ MeasureGUI_CheckShapeDlg_moc.cxx \ MeasureGUI_CheckCompoundOfBlocksDlg_moc.cxx \ + MeasureGUI_CheckSelfIntersectionsDlg_moc.cxx \ MeasureGUI_PointDlg_moc.cxx nodist_libMeasureGUI_la_SOURCES = \ diff --git a/src/MeasureGUI/MeasureGUI.cxx b/src/MeasureGUI/MeasureGUI.cxx index 60d7d56a4..7b21bcb05 100644 --- a/src/MeasureGUI/MeasureGUI.cxx +++ b/src/MeasureGUI/MeasureGUI.cxx @@ -18,12 +18,11 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // GEOM GEOMGUI : GUI for Geometry component // File : MeasureGUI.cxx // Author : Damien COQUERET, Open CASCADE S.A.S. -// + #include "MeasureGUI.h" #include @@ -42,6 +41,7 @@ #include "MeasureGUI_WhatisDlg.h" // Method WHATIS #include "MeasureGUI_CheckShapeDlg.h" // Method CHECKSHAPE #include "MeasureGUI_CheckCompoundOfBlocksDlg.h" // Method CHECKCOMPOUND +#include "MeasureGUI_CheckSelfIntersectionsDlg.h" // Method CHECK SELF INTERSCTIONS #include "MeasureGUI_PointDlg.h" // Method POINTCOORDINATES #include @@ -109,6 +109,9 @@ bool MeasureGUI::OnGUIEvent( int theCommandID, SUIT_Desktop* parent ) case GEOMOp::OpCheckCompound: dlg = new MeasureGUI_CheckCompoundOfBlocksDlg( getGeometryGUI(), parent ); break; // CHECKCOMPOUND + case GEOMOp::OpCheckSelfInters: + dlg = new MeasureGUI_CheckSelfIntersectionsDlg( getGeometryGUI(), parent ); + break; // CHECK SELF INTERSCTIONS case GEOMOp::OpPointCoordinates: dlg = new MeasureGUI_PointDlg( getGeometryGUI(), parent ); break; // POINT COORDINATES diff --git a/src/MeasureGUI/MeasureGUI_1Sel1TextView2ListBox_QTD.ui b/src/MeasureGUI/MeasureGUI_1Sel1TextView2ListBox_QTD.ui index eb01d0230..380f868ce 100644 --- a/src/MeasureGUI/MeasureGUI_1Sel1TextView2ListBox_QTD.ui +++ b/src/MeasureGUI/MeasureGUI_1Sel1TextView2ListBox_QTD.ui @@ -72,7 +72,14 @@ - + + + + 300 + 0 + + + diff --git a/src/MeasureGUI/MeasureGUI_CheckSelfIntersectionsDlg.cxx b/src/MeasureGUI/MeasureGUI_CheckSelfIntersectionsDlg.cxx new file mode 100644 index 000000000..886549598 --- /dev/null +++ b/src/MeasureGUI/MeasureGUI_CheckSelfIntersectionsDlg.cxx @@ -0,0 +1,249 @@ +// Copyright (C) 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 + +// GEOM GEOMGUI : GUI for Geometry component +// File : MeasureGUI_CheckSelfIntersectionsDlg.cxx +// Author : Vladimir KLYACHIN, Open CASCADE S.A.S. (vladimir.klyachin@opencascade.com) + +#include "MeasureGUI_CheckSelfIntersectionsDlg.h" +#include "MeasureGUI_Widgets.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#define TEXTEDIT_FONT_FAMILY "Courier" +#define TEXTEDIT_FONT_SIZE 11 + +//================================================================================= +// class : MeasureGUI_CheckSelfIntersectionsDlg() +// purpose : Constructs a MeasureGUI_CheckSelfIntersectionsDlg which is a child of 'parent', with the +// name 'name' and widget flags set to 'f'. +// The dialog will by default be modeless, unless you set 'modal' to +// true to construct a modal dialog. +//================================================================================= +MeasureGUI_CheckSelfIntersectionsDlg::MeasureGUI_CheckSelfIntersectionsDlg (GeometryGUI* GUI, QWidget* parent) + : MeasureGUI_Skeleton(GUI, parent, false) +{ + SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr(); + QPixmap image0 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_CHECK_SELF_INTERSECTIONS"))); + QPixmap image1 (aResMgr->loadPixmap("GEOM", tr("ICON_SELECT"))); + + setWindowTitle(tr("GEOM_CHECK_SELF_INTERSECTIONS")); + + /***************************************************************/ + mainFrame()->GroupConstructors->setTitle(tr("GEOM_CHECK_SELF_INTERSECTIONS")); + mainFrame()->RadioButton1->setIcon(image0); + + myGrp = new MeasureGUI_1Sel1TextView2ListBox (centralWidget()); + myGrp->GroupBox1->setTitle(tr("GEOM_CHECK_INFOS")); + myGrp->TextLabel1->setText(tr("GEOM_OBJECT")); + + myGrp->TextView1->setReadOnly(true); + QFont aFont (TEXTEDIT_FONT_FAMILY, TEXTEDIT_FONT_SIZE); + aFont.setStyleHint(QFont::TypeWriter, QFont::PreferAntialias); + myGrp->TextView1->setFont(aFont); + + myGrp->PushButton1->setIcon(image1); + myGrp->LineEdit1->setReadOnly(true); + + myGrp->TextLabel2->setText(tr("GEOM_CHECK_BLOCKS_COMPOUND_ERRORS")); + myGrp->TextLabel3->setText(tr("GEOM_CHECK_BLOCKS_COMPOUND_SUBSHAPES")); + + myGrp->ListBox2->setSelectionMode(QAbstractItemView::ExtendedSelection); + + QVBoxLayout* layout = new QVBoxLayout (centralWidget()); + layout->setMargin(0); layout->setSpacing(6); + layout->addWidget(myGrp); + + /***************************************************************/ + + myHelpFileName = "using_measurement_tools_page.html#check_self_intersections_anchor"; + + /* Initialisation */ + Init(); +} + +//================================================================================= +// function : ~MeasureGUI_CheckSelfIntersectionsDlg() +// purpose : Destroys the object and frees any allocated resources +//================================================================================= +MeasureGUI_CheckSelfIntersectionsDlg::~MeasureGUI_CheckSelfIntersectionsDlg() +{ +} + +//================================================================================= +// function : Init() +// purpose : +//================================================================================= +void MeasureGUI_CheckSelfIntersectionsDlg::Init() +{ + mySelBtn = myGrp->PushButton1; + mySelEdit = myGrp->LineEdit1; + MeasureGUI_Skeleton::Init(); + + connect(myGrp->ListBox1, SIGNAL(itemSelectionChanged()), SLOT(onErrorsListSelectionChanged())); + connect(myGrp->ListBox2, SIGNAL(itemSelectionChanged()), SLOT(onSubShapesListSelectionChanged())); +} + +//================================================================================= +// function : processObject +// purpose : +//================================================================================= +void MeasureGUI_CheckSelfIntersectionsDlg::processObject() +{ + myGrp->ListBox1->clear(); + myGrp->ListBox2->clear(); + erasePreview(); + + if (myObj->_is_nil()) + return; + + QString aMsg (""); + GEOM::GEOM_IMeasureOperations_var anOper = GEOM::GEOM_IMeasureOperations::_narrow(getOperation()); + bool isGood = false, isFailed = false; + int nbPairs = 0; + try { + isGood = anOper->CheckSelfIntersections(myObj, myInters); + nbPairs = myInters->length()/2; + if (nbPairs*2 != myInters->length()) { + isFailed = true; + } + } + catch (const SALOME::SALOME_Exception& e) { + SalomeApp_Tools::QtCatchCorbaException(e); + isFailed = true; + } + if (isFailed) { + aMsg += tr("GEOM_CHECK_SELF_INTERSECTIONS_FAILED"); + myGrp->TextView1->setText(aMsg); + return; + } + + // Status + if (isGood) { + aMsg += tr("GEOM_NO_SELF_INTERSECTIONS"); + } + else { + aMsg += tr("GEOM_SELF_INTERSECTIONS_FOUND"); + } + myGrp->TextView1->setText(aMsg); + + // Pairs + QStringList aErrList; + QString aErrStr (""); + for (int i = 1; i <= nbPairs; i++) { + aErrStr = "Intersection # "; + aErrStr += QString::number(i); + aErrList.append(aErrStr); + } + + myGrp->ListBox1->addItems(aErrList); +} + +//================================================================================= +// function : onErrorsListSelectionChanged +// purpose : +//================================================================================= +void MeasureGUI_CheckSelfIntersectionsDlg::onErrorsListSelectionChanged() +{ + erasePreview(); + int aCurItem = myGrp->ListBox1->currentRow(); + if (aCurItem < 0) + return; + + //int nbPairs = myInters->length()/2; + + QStringList aSubShapeList; + TopoDS_Shape aSelShape; + if (!myObj->_is_nil() && GEOMBase::GetShape(myObj, aSelShape)) { + TopTools_IndexedMapOfShape anIndices; + TopExp::MapShapes(aSelShape, anIndices); + + TopoDS_Shape aSubShape = anIndices.FindKey(myInters[aCurItem*2]); + QString aType = GEOMBase::GetShapeTypeString(aSubShape); + if (!aType.isEmpty()) + aSubShapeList.append(QString("%1_%2").arg(aType).arg(myInters[aCurItem*2])); + aSubShape = anIndices.FindKey(myInters[aCurItem*2 + 1]); + aType = GEOMBase::GetShapeTypeString(aSubShape); + if (!aType.isEmpty()) + aSubShapeList.append(QString("%1_%2").arg(aType).arg(myInters[aCurItem*2 + 1])); + } + myGrp->ListBox2->clear(); + myGrp->ListBox2->addItems(aSubShapeList); +} + +//================================================================================= +// function : onSubShapesListSelectionChanged +// purpose : +//================================================================================= +void MeasureGUI_CheckSelfIntersectionsDlg::onSubShapesListSelectionChanged() +{ + erasePreview(); + + // Current pair + int aErrCurItem = myGrp->ListBox1->currentRow(); + if (aErrCurItem < 0) + return; + + // Selected IDs + QList aIds; + for (int i = 0, n = myGrp->ListBox2->count(); i < n; i++) { + if (myGrp->ListBox2->item(i)->isSelected()) + aIds.append(i); + } + if (aIds.count() < 1) + return; + + TopoDS_Shape aSelShape; + TopoDS_Shape aSubShape; + TopTools_IndexedMapOfShape anIndices; + if (!myObj->_is_nil() && GEOMBase::GetShape(myObj, aSelShape)) { + SALOME_Prs* aPrs = 0; + TopExp::MapShapes(aSelShape, anIndices); + QList::iterator it; + for (it = aIds.begin(); it != aIds.end(); ++it) { + aSubShape = anIndices.FindKey(myInters[aErrCurItem*2 + (*it)]); + try { + getDisplayer()->SetColor(Quantity_NOC_RED); + getDisplayer()->SetWidth(3); + getDisplayer()->SetToActivate(false); + aPrs = !aSubShape.IsNull() ? getDisplayer()->BuildPrs(aSubShape) : 0; + if (aPrs) + displayPreview(aPrs, true); + } + catch (const SALOME::SALOME_Exception& e) { + SalomeApp_Tools::QtCatchCorbaException(e); + } + } + } +} diff --git a/src/MeasureGUI/MeasureGUI_CheckSelfIntersectionsDlg.h b/src/MeasureGUI/MeasureGUI_CheckSelfIntersectionsDlg.h new file mode 100644 index 000000000..c98ec1365 --- /dev/null +++ b/src/MeasureGUI/MeasureGUI_CheckSelfIntersectionsDlg.h @@ -0,0 +1,62 @@ +// Copyright (C) 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 + +// GEOM GEOMGUI : GUI for Geometry component +// File : MeasureGUI_CheckSelfIntersectionsDlg.h + +#ifndef MEASUREGUI_CHECKSELFINTERDLG_H +#define MEASUREGUI_CHECKSELFINTERDLG_H + +#include + +class MeasureGUI_1Sel1TextView2ListBox; + +//================================================================================= +// class : MeasureGUI_CheckSelfIntersectionsDlg +// purpose : +//================================================================================= + +class MeasureGUI_CheckSelfIntersectionsDlg : public MeasureGUI_Skeleton +{ + Q_OBJECT + +public: + MeasureGUI_CheckSelfIntersectionsDlg(GeometryGUI*, QWidget*); + ~MeasureGUI_CheckSelfIntersectionsDlg(); + +protected: + // redefined from GEOMBase_Helper and MeasureGUI_Skeleton + virtual void processObject(); + +private slots: + void onErrorsListSelectionChanged(); + void onSubShapesListSelectionChanged(); + +private: + void Init(); + +private: + MeasureGUI_1Sel1TextView2ListBox* myGrp; + + GEOM::ListOfLong_var myInters; +}; + +#endif // MEASUREGUI_CHECKSELFINTERDLG_H diff --git a/src/NMTDS/NMTDS_Tools.cxx b/src/NMTDS/NMTDS_Tools.cxx index 5c4a25d07..03755e6dd 100644 --- a/src/NMTDS/NMTDS_Tools.cxx +++ b/src/NMTDS/NMTDS_Tools.cxx @@ -15,13 +15,11 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // File: NMTDS_Tools.cxx // Created: Tue Feb 20 14:57:28 2007 // Author: Peter KURNEV -// -// + #include #include #include @@ -32,15 +30,15 @@ #include #include -void CopySource(const TopoDS_Shape& aS, - TopTools_IndexedDataMapOfShapeShape& aMapSS, +void CopySource(const TopoDS_Shape& aS, + TopTools_IndexedDataMapOfShapeShape& aMapSS, TopoDS_Shape& aSC); //======================================================================= //function : CopyShape -//purpose : +//purpose : //======================================================================= - void NMTDS_Tools::CopyShape(const TopoDS_Shape& aS, + void NMTDS_Tools::CopyShape(const TopoDS_Shape& aS, TopoDS_Shape& aSC) { TopTools_IndexedDataMapOfShapeShape aMapSS; @@ -49,9 +47,9 @@ void CopySource(const TopoDS_Shape& aS, } //======================================================================= //function : CopyShape -//purpose : +//purpose : //======================================================================= - void NMTDS_Tools::CopyShape(const TopoDS_Shape& aS, + void NMTDS_Tools::CopyShape(const TopoDS_Shape& aS, TopoDS_Shape& aSC, TopTools_IndexedDataMapOfShapeShape& aMapSS) { @@ -59,15 +57,16 @@ void CopySource(const TopoDS_Shape& aS, } //======================================================================= //function : CopySource -//purpose : +//purpose : //======================================================================= -void CopySource(const TopoDS_Shape& aS, - TopTools_IndexedDataMapOfShapeShape& aMapSS, +void CopySource(const TopoDS_Shape& aS, + TopTools_IndexedDataMapOfShapeShape& aMapSS, TopoDS_Shape& aSC) { Standard_Boolean bFree; TopAbs_ShapeEnum aT; TopoDS_Iterator aIt; + TopoDS_Shape aSF; BRep_Builder BB; // aT=aS.ShapeType(); @@ -84,13 +83,25 @@ void CopySource(const TopoDS_Shape& aS, // bFree=aSC.Free(); aSC.Free(Standard_True); - aIt.Initialize(aS); + //modified by NIZNHY-PKV Fri Nov 25 10:10:03 2011f + aSF=aS; + if (aT==TopAbs_EDGE){ + TopAbs_Orientation aOr; + // + aOr=aS.Orientation(); + if(aOr==TopAbs_INTERNAL) { + aSF.Orientation(TopAbs_FORWARD); + } + } + aIt.Initialize(aSF); + //aIt.Initialize(aS); + //modified by NIZNHY-PKV Fri Nov 25 10:10:05 2011t for (; aIt.More(); aIt.Next()) { TopoDS_Shape aSCx; // const TopoDS_Shape& aSx=aIt.Value(); // - CopySource (aSx, aMapSS, aSCx); + CopySource (aSx, aMapSS, aSCx); // aSCx.Orientation(aSx.Orientation()); BB.Add(aSC, aSCx); @@ -99,9 +110,9 @@ void CopySource(const TopoDS_Shape& aS, } //======================================================================= // function: ComputeVV -// purpose: +// purpose: //======================================================================= - Standard_Integer NMTDS_Tools::ComputeVV(const TopoDS_Vertex& aV1, + Standard_Integer NMTDS_Tools::ComputeVV(const TopoDS_Vertex& aV1, const TopoDS_Vertex& aV2) { Standard_Real aTolV1, aTolV2, aTolSum, aTolSum2, aD2; @@ -123,7 +134,7 @@ void CopySource(const TopoDS_Shape& aS, } //======================================================================= // function: HasBRep -// purpose: +// purpose: //======================================================================= Standard_Boolean NMTDS_Tools::HasBRep(const TopAbs_ShapeEnum aTi) { @@ -131,7 +142,7 @@ void CopySource(const TopoDS_Shape& aS, } //======================================================================= //function : TypeToInteger -//purpose : +//purpose : //======================================================================= Standard_Integer NMTDS_Tools::TypeToInteger(const TopAbs_ShapeEnum aType1, const TopAbs_ShapeEnum aType2) @@ -168,5 +179,5 @@ void CopySource(const TopoDS_Shape& aS, default: break; } - return iRet; + return iRet; }