From: vsr Date: Wed, 28 Jan 2015 15:16:24 +0000 (+0300) Subject: Merge branch occ/shape_reparation_2 X-Git-Tag: V7_6_0a1~60 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=97c05bd172eb333540395044a41bb3e1160ffc48;p=modules%2Fgeom.git Merge branch occ/shape_reparation_2 --- 97c05bd172eb333540395044a41bb3e1160ffc48 diff --cc doc/salome/gui/GEOM/input/creating_explode.doc index 65a813eb2,6caf20df1..c25b719ae --- a/doc/salome/gui/GEOM/input/creating_explode.doc +++ b/doc/salome/gui/GEOM/input/creating_explode.doc @@@ -9,42 -12,86 +12,86 @@@ To create a list of sub-shapes (vertic given shape using the \b Explode operation, you need to define the Main Object, which will be exploded and the Type of Sub-shapes you wish to obtain from it. - \n The \b Result of the operation will be a List of \b GEOM_Objects + + The \b Result of the operation will be a List of \b GEOM_Objects (vertexes, edges, wires, faces, shells or solids). - \n Using TUI Commands you can perform this operation in a + Available choices in the Sub Shapes Type combo box depend on the type + of selected Main Object: + - \b Compound: to extract compounds; + - \b Compsolid: to extract compsolids; + - \b Solid: to extract solids; + - \b Shell: to extract shells; + - \b Face: to extract faces; + - \b Wire: to extract wires; + - \b Edge: to extract edges; + - \b Vertex: to extract vertices; + - \b Shape: to extract top-level contents of the compound shape; + - \b Flat: to extract "flat" contents of the compound shape. + + Note: "flat" contents means top-level simple-type sub-shapes extracted from + the compound object recursively (i.e. there is no compounds in the result). + For example, if a compound C1 contains a solid S1 and another compound C2 that + contains solids S2 and S3 (see picture below): + - Explode operation with \b Shape type given as parameter will return S1 and C2; + - Explode operation with \b Flat type given as parameter will return S1, S2 and S3. + + \image html flat_contents.png + + Switching on Select Sub-shapes check box allows manual selection of sub-shapes + to be extracted from the main object. In this mode the user can select sub-shapes + directly in 3D viewer. + + When Select Sub-shapes check box is switched on, additional \b Filter controls + allow to automatically pick up entites which satisfy specified threshold value(s). + The numerical functor for each sub-shape that is compared with threshold value(s) + is computed according to the shape's topological properties: + - length for edges and wires + - area for faces and shells + - volume for solids, compounds, compsolids + + Filtering capabilities are not available for vertices. + + In order to filter out some entities: + - Activate one or two filtering controls by switching on corresponding check boxes; + - Select required threshold comparator type; the following choices are available: + - Less Than or Equal or Less Than for the first comparator; + - Greater Than or Equal or Greater Than for the second comparator; + - Enter required threshold value (values); + - Press \b Apply button in the \b Filter group. + + The entities which satisfy entered filtering parameters will be automatically highlighted + in the 3D viewer. + + Using TUI Commands you can perform this operation in a variety of ways: - - - \n Arguments: 1 SHAPE + 1 type of SubShape. + - geompy.ExtractShapes(Shape, Type, isSorted) explodes a + Shape into sub-shapes of a given Type and returns a List of sub-shapes. + This method does not return the Shape itself if it matches the + Type. + - geompy.SubShapeAll(Shape, Type) explodes a Shape on + sub-shapes of a given Type and returns a List of sub-shapes. + - geompy.SubShapeAllIDs(Shape, Type) explodes a Shape on + sub-shapes of a given Type and returns a List of IDs of + sub-shapes. + - geompy.SubShapeAllSortedCentres(Shape, Type) explodes a + shape on sub-shapes of a given type and sorts them taking into account - their gravity centers, to provide stable order of sub-shapes. ++ their gravity centers, to provide a stable order of sub-shapes. + It returns a list of sub-shapes. + - geompy.SubShapeAllSortedCentresIDs(Shape, Type) explodes + a shape on sub-shapes of a given type and sorts them taking into - account their gravity centers, to provide stable order of sub-shapes. ++ account their gravity centers, to provide a stable order of sub-shapes. + It returns a List of IDs of sub-shapes. + - geompy.SubShape(Shape, Type, ListOfInd) allows to obtain + a compound of sub-shapes of the Shape, selected by they indices in a + list of all sub-shapes of the given Type. Each index is in the range + [1, Nb_Sub-Shapes_Of_Given_Type]. + - geompy.SubShapeSortedCentres(Shape, Type, ListOfInd) + allows to obtain a compound of sub-shapes of the Shape, selected by + they indices in sorted list of all sub-shapes of the given Type. Each + index is in the range [1, Nb_Sub-Shapes_Of_Given_Type] - \image html neo-obj1.png + Arguments: 1 SHAPE + 1 type of SubShape. Example: diff --cc doc/salome/gui/GEOM/input/dependency_tree.doc index 9afc744bc,15a3a7639..2f07c9bd3 --- a/doc/salome/gui/GEOM/input/dependency_tree.doc +++ b/doc/salome/gui/GEOM/input/dependency_tree.doc @@@ -86,9 -103,10 +86,9 @@@ Buttons marked with small downward tria functionality which can be accessed by locking on them with left mouse button. - \image tree_tool_bar + \image html tree_tool_bar.png -Dump View - exports an object from the viewer in bmp, png or -jpeg image format. +Dump View - exports the current scene in bmp, png or jpeg image format. \image html tree_view_dump.png Fit all - scales the presentation so that it could fit within diff --cc doc/salome/gui/GEOM/input/tui_basic_geom_objs.doc index d7edb5227,2083bcc46..4d141752b --- a/doc/salome/gui/GEOM/input/tui_basic_geom_objs.doc +++ b/doc/salome/gui/GEOM/input/tui_basic_geom_objs.doc @@@ -38,8 -38,8 +38,12 @@@

Creation of a Local Coordinate System

\tui_script{basic_geom_objs_ex09.py} + \anchor tui_creation_surface +

Creation of a Surface From Face

+ \tui_script{basic_geom_objs_ex10.py} + +\anchor tui_creation_polyline +

Creation of 2D Polyline

+\tui_script{polyline.py} + */ diff --cc doc/salome/gui/GEOM/input/tui_test_all.doc index e2ecdac38,56beffc5d..1718afb00 --- a/doc/salome/gui/GEOM/input/tui_test_all.doc +++ b/doc/salome/gui/GEOM/input/tui_test_all.doc @@@ -66,6 -66,6 +66,12 @@@ \anchor swig_ChangeOrientation \until ChangeOrientation ++\anchor swig_ExtendFaceEdge ++\until ExtendFace ++ ++\anchor swig_SurfaceFromFace ++\until MakeSurfaceFromFace ++ \anchor swig_ExtractShapes \until prism_edges diff --cc idl/GEOM_Gen.idl index 2917f62cf,26412f7e5..5ea2b1b2d --- a/idl/GEOM_Gen.idl +++ b/idl/GEOM_Gen.idl @@@ -2516,15 -2610,53 +2610,62 @@@ module GEO ListOfLong GetSameIDs (in GEOM_Object theShapeWhere, in GEOM_Object theShapeWhat); + /*! + * \brief Resize the input edge with the new Min and Max parameters. + * The input edge parameters range is [0, 1]. If theMin parameter is + * negative, the input edge is extended, otherwise it is shrinked by + * theMin parameter. If theMax is greater than 1, the edge is extended, + * otherwise it is shrinked by theMax parameter. + * \param theEdge the input edge to be resized. + * \param theMin the minimal parameter value. + * \param theMax the maximal parameter value. + * \return a newly created edge. + */ + GEOM_Object ExtendEdge(in GEOM_Object theEdge, + in double theMin, + in double theMax); + + /*! + * \brief Resize the input face with the new UMin, UMax, VMin and VMax + * parameters. The input face U and V parameters range is [0, 1]. If + * theUMin parameter is negative, the input face is extended, otherwise + * it is shrinked along U direction by theUMin parameter. If theUMax is + * greater than 1, the face is extended, otherwise it is shrinked along + * U direction by theUMax parameter. So as for theVMin, theVMax and + * V direction of the input face. + * \param theFace the input face to be resized. + * \param theUMin the minimal U parameter value. + * \param theUMax the maximal U parameter value. + * \param theVMin the minimal V parameter value. + * \param theVMax the maximal V parameter value. + * \return a newly created face. + */ + GEOM_Object ExtendFace(in GEOM_Object theFace, + in double theUMin, + in double theUMax, + in double theVMin, + in double theVMax); + + /*! + * \brief Make a surface from a face. This function takes some face as + * input parameter and creates new GEOM_Object, i.e. topological shape + * by extracting underlying surface of the source face and limiting it + * by the Umin, Umax, Vmin, Vmax parameters of the source face (in the + * parametrical space). + * \param theFace the input face. + * \return a newly created face. + */ + GEOM_Object MakeSurfaceFromFace(in GEOM_Object theFace); + + /*! + * \brief Explode a shape into edges sorted in a row from a starting point. + * \param theShape - the shape to be exploded on edges. + * \param theStartPoint - the starting point. + * \return Ordered list of edges sorted in a row from a starting point. + */ + ListOfGO GetSubShapeEdgeSorted (in GEOM_Object theShape, + in GEOM_Object theStartPoint); + }; // # GEOM_IBlocksOperations: diff --cc src/GEOMImpl/GEOMImpl_HealingDriver.cxx index 966cd0334,51154eb63..edce49658 --- a/src/GEOMImpl/GEOMImpl_HealingDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_HealingDriver.cxx @@@ -542,14 -655,84 +651,79 @@@ void GEOMImpl_HealingDriver::LimitToler // 1. Make a copy to prevent the original shape changes. TopoDS_Shape aShapeCopy; - TColStd_IndexedDataMapOfTransientTransient aMapTShapes; - TNaming_CopyShape::CopyTool(theOriginalShape, aMapTShapes, aShapeCopy); + { + TColStd_IndexedDataMapOfTransientTransient aMapTShapes; + TNaming_CopyShape::CopyTool(theOriginalShape, aMapTShapes, aShapeCopy); + } - // 2. Limit tolerance. - ShapeFix_ShapeTolerance aSFT; - aSFT.LimitTolerance(aShapeCopy, aTol, aTol, TopAbs_SHAPE); - // 3. Fix obtained shape. - Handle(ShapeFix_Shape) aSfs = new ShapeFix_Shape (aShapeCopy); - aSfs->Perform(); - theOutShape = aSfs->Shape(); - - BRepCheck_Analyzer ana (theOutShape, Standard_True); - if (!ana.IsValid()) + // 2. Limit tolerance. + if (!GEOMUtils::FixShapeTolerance(aShapeCopy, aType, aTol)) StdFail_NotDone::Raise("Non valid shape result"); ++ // 3. Set the result + theOutShape = aShapeCopy; ++ + // 4. Collect statistics + { + ShHealOper_Tool tool; + ShHealOper_ModifStats& stats = tool.GetStatistics(); + + int nb[3] = { 0,0,0 }; + TopTools_IndexedMapOfShape aShapes; + TopExp::MapShapes( theOutShape, TopAbs_VERTEX, aShapes); + for ( int i = 1; i <= aShapes.Extent(); ++i ) + { + const TopoDS_Vertex& v = TopoDS::Vertex( aShapes( i )); + double tol = BRep_Tool::Tolerance( v ); + if ( tol < aTol ) nb[0]++; + else if ( tol > aTol ) nb[2]++; + else nb[1]++; + } + if ( nb[0] > 0 ) + stats.AddModif( "Tolerance of vertex decreased for shape validity", nb[0] ); + if ( nb[1] > 0 ) + stats.AddModif( "Tolerance of vertex limited as requested", nb[1] ); + if ( nb[2] > 0 ) + stats.AddModif( "Tolerance of vertex increased for shape validity", nb[2] ); + + nb[0] = nb[1] = nb[2] = 0; + aShapes.Clear(); + TopExp::MapShapes( theOutShape, TopAbs_EDGE, aShapes); + for ( int i = 1; i <= aShapes.Extent(); ++i ) + { + const TopoDS_Edge& e = TopoDS::Edge( aShapes( i )); + double tol = BRep_Tool::Tolerance( e ); + if ( tol < aTol ) nb[0]++; + else if ( tol > aTol ) nb[2]++; + else nb[1]++; + } + if ( nb[0] > 0 ) + stats.AddModif( "Tolerance of edge decreased for shape validity", nb[0] ); + if ( nb[1] > 0 ) + stats.AddModif( "Tolerance of edge limited as requested", nb[1] ); + if ( nb[2] > 0 ) + stats.AddModif( "Tolerance of edge increased for shape validity", nb[2] ); + + nb[0] = nb[1] = nb[2] = 0; + aShapes.Clear(); + TopExp::MapShapes( theOutShape, TopAbs_FACE, aShapes); + for ( int i = 1; i <= aShapes.Extent(); ++i ) + { + const TopoDS_Face& f = TopoDS::Face( aShapes( i )); + double tol = BRep_Tool::Tolerance( f ); + if ( tol < aTol ) nb[0]++; + else if ( tol > aTol ) nb[2]++; + else nb[1]++; + } + if ( nb[0] > 0 ) + stats.AddModif( "Tolerance of face decreased for shape validity", nb[0] ); + if ( nb[1] > 0 ) + stats.AddModif( "Tolerance of face limited as requested", nb[1] ); + if ( nb[2] > 0 ) + stats.AddModif( "Tolerance of face increased for shape validity", nb[2] ); + + SaveStatistics( tool ); + } } //======================================================================= diff --cc src/GEOMImpl/GEOMImpl_IHealing.hxx index 4324a6662,06e354db2..c0284e7e2 --- a/src/GEOMImpl/GEOMImpl_IHealing.hxx +++ b/src/GEOMImpl/GEOMImpl_IHealing.hxx @@@ -24,8 -24,8 +24,9 @@@ #include #include -#include "TColStd_HSequenceOfTransient.hxx" +#include +#include + #include class GEOMImpl_IHealing { @@@ -89,6 -86,24 +90,24 @@@ public Handle(TColStd_HSequenceOfTransient) GetShapes() { return _func->GetReferenceList(ARG_LIST_SHAPES); } + Handle(TColStd_HSequenceOfTransient) GetOriginalAndShapes() + { + Handle(TColStd_HSequenceOfTransient) funs = GetShapes(); + if ( funs.IsNull() ) funs = new TColStd_HSequenceOfTransient; + funs->Prepend( GetOriginal() ); + return funs; + } + - void SetStatistics( ShHealOper_ModifStats * ms ) ++ void SetStatistics( ShHealOper_ModifStats* ms ) + { + if ( ms ) ms->Clear(); + _func->SetCallBackData( (void*) ms ); + } - ShHealOper_ModifStats * GetStatistics() ++ ShHealOper_ModifStats* GetStatistics() + { + return (ShHealOper_ModifStats*) _func->GetCallBackData(); + } + private: Handle(GEOM_Function) _func; }; diff --cc src/GEOMImpl/GEOMImpl_IHealingOperations.cxx index 443ae83d6,865867dac..43aee783e --- a/src/GEOMImpl/GEOMImpl_IHealingOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IHealingOperations.cxx @@@ -1085,7 -1203,7 +1204,8 @@@ Handle(GEOM_Object) GEOMImpl_IHealingOp GEOMImpl_IHealing HI (aFunction); HI.SetOriginal(aLastFunction); HI.SetTolerance(theTolerance); + HI.SetType(theType); + HI.SetStatistics( myModifStats ); // Compute try { diff --cc src/GEOMImpl/GEOMImpl_IHealingOperations.hxx index 77c9fa392,df2952a9a..af111fff0 --- a/src/GEOMImpl/GEOMImpl_IHealingOperations.hxx +++ b/src/GEOMImpl/GEOMImpl_IHealingOperations.hxx @@@ -97,9 -102,13 +103,14 @@@ class GEOMImpl_IHealingOperations : pub Standard_EXPORT Handle(GEOM_Object) ChangeOrientationCopy( Handle(GEOM_Object) theObject); Standard_EXPORT Handle(GEOM_Object) LimitTolerance( Handle(GEOM_Object) theObject, - double theTolerance ); + double theTolerance, + TopAbs_ShapeEnum theType = TopAbs_SHAPE ); + const ShHealOper_ModifStats* GetStatistics() { return myModifStats; } + + private: + + ShHealOper_ModifStats* myModifStats; }; #endif diff --cc src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx index 0cf9dd339,3d7601a76..ae0103de6 --- a/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx @@@ -20,6 -20,6 +20,8 @@@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // ++#include ++ #include #include #include @@@ -48,6 -49,7 +51,9 @@@ #include #include #include ++#if OCC_VERSION_LARGE > 0x06080000 + #include ++#endif #include #include #include @@@ -1573,6 -1577,88 +1581,93 @@@ bool GEOMImpl_IMeasureOperations::Check return isGood; } + //============================================================================= + /*! + * FastIntersect + */ + //============================================================================= + bool GEOMImpl_IMeasureOperations::FastIntersect (Handle(GEOM_Object) theShape1, Handle(GEOM_Object) theShape2, + double theTolerance, float theDeflection, + Handle(TColStd_HSequenceOfInteger)& theIntersections1, + Handle(TColStd_HSequenceOfInteger)& theIntersections2) + { + SetErrorCode(KO); + bool isGood = false; + ++#if OCC_VERSION_LARGE > 0x06080000 ++ + if (theIntersections1.IsNull()) + theIntersections1 = new TColStd_HSequenceOfInteger; + else + theIntersections1->Clear(); + + if (theIntersections2.IsNull()) + theIntersections2 = new TColStd_HSequenceOfInteger; + else + theIntersections2->Clear(); + + if (theShape1.IsNull() || theShape2.IsNull()) { + SetErrorCode("Objects have NULL Shape"); + return isGood; + } + + if (theShape1 == theShape2) { + SetErrorCode("Objects are equal"); + return isGood; + } + Handle(GEOM_Function) aRefShape1 = theShape1->GetLastFunction(); + Handle(GEOM_Function) aRefShape2 = theShape2->GetLastFunction(); + if (aRefShape1.IsNull() || aRefShape2.IsNull()) return isGood; + + TopoDS_Shape aShape1 = aRefShape1->GetValue(); + TopoDS_Shape aShape2 = aRefShape2->GetValue(); + if (aShape1.IsNull() || aShape2.IsNull()) return isGood; + + // 0. Prepare data + TopoDS_Shape aScopy1, aScopy2; + GEOMAlgo_AlgoTools::CopyShape(aShape1, aScopy1); + GEOMAlgo_AlgoTools::CopyShape(aShape2, aScopy2); + + float aDeflection = (theDeflection <= 0.) ? 0.001 : theDeflection; + GEOM::MeshShape(aScopy1, aDeflection); + GEOM::MeshShape(aScopy2, aDeflection); + // + // Map sub-shapes and their indices + TopTools_IndexedMapOfShape anIndices1, anIndices2; + TopExp::MapShapes(aScopy1, anIndices1); + TopExp::MapShapes(aScopy2, anIndices2); + + BOPCol_ListOfShape aLCS1, aLCS2; + aLCS1.Append(aScopy1); aLCS2.Append(aScopy2); + // + BRepExtrema_ShapeProximity aBSP; // checker of fast interferences + aBSP.LoadShape1(aScopy1); aBSP.LoadShape2(aScopy2); + aBSP.SetTolerance((theTolerance <= 0.) ? 0.0 : theTolerance); + + // 1. Launch the checker + aBSP.Perform(); + + // 2. Get sets of IDs of overlapped faces + for (BRepExtrema_OverlappedSubShapes::Iterator anIt1 (aBSP.OverlapSubShapes1()); anIt1.More(); anIt1.Next()) { + const TopoDS_Shape& aS1 = aBSP.GetSubShape1(anIt1.Key()); + theIntersections1->Append(anIndices1.FindIndex(aS1)); + } + + for (BRepExtrema_OverlappedSubShapes::Iterator anIt2 (aBSP.OverlapSubShapes2()); anIt2.More(); anIt2.Next()) { + const TopoDS_Shape& aS2 = aBSP.GetSubShape2(anIt2.Key()); + theIntersections2->Append(anIndices2.FindIndex(aS2)); + } + + isGood = !theIntersections1->IsEmpty() && !theIntersections1->IsEmpty(); + + if (aBSP.IsDone()) + SetErrorCode(OK); + ++#endif // OCC_VERSION_LARGE > 0x06080000 ++ + return isGood; + } ++ //============================================================================= /*! * IsGoodForSolid diff --cc src/GEOMImpl/GEOMImpl_IShapesOperations.cxx index f7df593ad,9f1ee5e88..da74684cb --- a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx @@@ -132,57 -103,24 +103,64 @@@ #include #include // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC - // Includes added for GetInPlace algorithm improvement - - #include - #include - #include + namespace { - #include - #include - #include + void AddFlatSubShapes(const TopoDS_Shape& S, TopTools_ListOfShape& L, TopTools_MapOfShape& M) + { + if (S.ShapeType() != TopAbs_COMPOUND) { + L.Append(S); + } + else { + TopoDS_Iterator It(S, Standard_True, Standard_True); + for (; It.More(); It.Next()) { + TopoDS_Shape SS = It.Value(); + if (M.Add(SS)) + AddFlatSubShapes(SS, L, M); + } + } + } + } +namespace +{ + const double MAX_TOLERANCE = 1.e-7; + + /** + * \brief Returns the vertex from theWhere shape that is coincident with + * theVertex. + * + * \param theWhere the shape where the coinsident vertex is searched. + * \param theVertex the vertex to be searched. + * \return the coincident vertex if it is found. Otherwise null object. + */ + static TopoDS_Vertex getSameVertex(const TopoDS_Shape &theWhere, + const TopoDS_Vertex &theVertex) + { + TopoDS_Vertex aResult; + gp_Pnt aPoint = BRep_Tool::Pnt(theVertex); + TopExp_Explorer anExp(theWhere, TopAbs_VERTEX); + TopTools_MapOfShape aMap; + + for(; anExp.More(); anExp.Next()) { + const TopoDS_Shape &aLocalShape = anExp.Current(); + + if(!aMap.Add(aLocalShape)) { + continue; + } + + TopoDS_Vertex aVertex = TopoDS::Vertex(aLocalShape); + gp_Pnt aPoint2 = BRep_Tool::Pnt(aVertex); + + if(aPoint.Distance(aPoint2) <= MAX_TOLERANCE) { + aResult = aVertex; + break; + } + } + + return aResult; + } +} // end of namespace + //============================================================================= /*! * constructor: diff --cc src/GEOMImpl/GEOMImpl_IShapesOperations.hxx index 59af88e00,002f338e6..0b767615f --- a/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx +++ b/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx @@@ -383,16 -388,21 +388,66 @@@ class GEOMImpl_IShapesOperations : publ const Standard_Integer theShapeType, GEOMAlgo_State theState); ++ /*! ++ * \brief Resize the input edge with the new Min and Max parameters. ++ * The input edge parameters range is [0, 1]. If theMin parameter is ++ * negative, the input edge is extended, otherwise it is shrinked by ++ * theMin parameter. If theMax is greater than 1, the edge is extended, ++ * otherwise it is shrinked by theMax parameter ++ * \param theEdge the input edge to be resized ++ * \param theMin the minimal parameter value ++ * \param theMax the maximal parameter value ++ * \retval Handle(GEOM_Object) - newly created edge ++ */ + Standard_EXPORT Handle(GEOM_Object) - ExtendEdge(const Handle(GEOM_Object) &theEdge, ++ ExtendEdge(const Handle(GEOM_Object)& theEdge, + const Standard_Real theMin, + const Standard_Real theMax); + ++ /*! ++ * \brief Resize the input face with the new UMin, UMax, VMin and VMax ++ * parameters. The input face U and V parameters range is [0, 1]. If ++ * theUMin parameter is negative, the input face is extended, otherwise ++ * it is shrinked along U direction by theUMin parameter. If theUMax is ++ * greater than 1, the face is extended, otherwise it is shrinked along ++ * U direction by theUMax parameter. So as for theVMin, theVMax and ++ * V direction of the input face. ++ * \param theFace the input face to be resized ++ * \param theUMin the minimal U parameter value ++ * \param theUMax the maximal U parameter value ++ * \param theVMin the minimal V parameter value ++ * \param theVMax the maximal V parameter value ++ * \retval Handle(GEOM_Object) - newly created face ++ */ + Standard_EXPORT Handle(GEOM_Object) - ExtendFace(const Handle(GEOM_Object) &theFace, ++ ExtendFace(const Handle(GEOM_Object)& theFace, + const Standard_Real theUMin, + const Standard_Real theUMax, + const Standard_Real theVMin, + const Standard_Real theVMax); - ++ ++ /*! ++ * \brief Make a surface from a face. This function takes some face as ++ * input parameter and creates new GEOM_Object, i.e. topological shape ++ * by extracting underlying surface of the source face and limiting it ++ * by the Umin, Umax, Vmin, Vmax parameters of the source face (in the ++ * parametrical space). ++ * \param theFace the input face ++ * \retval Handle(GEOM_Object) - newly created face ++ */ + Standard_EXPORT Handle(GEOM_Object) + MakeSurfaceFromFace(const Handle(GEOM_Object) &theFace); + + /*! + * \brief Explode a shape into edges sorted in a row from a starting point. + * \param theShape - the shape to be exploded on edges. + * \param theStartPoint - the starting point. + * \return Ordered list of edges sorted in a row from a starting point. + */ + Standard_EXPORT Handle(TColStd_HSequenceOfTransient) + GetSubShapeEdgeSorted (const Handle(GEOM_Object) &theShape, + const Handle(GEOM_Object) &theStartPoint); + private: Handle(GEOM_Object) MakeShape (std::list theShapes, const Standard_Integer theObjectType, diff --cc src/GEOMUtils/GEOMUtils.cxx index 055276d89,5b5cc2574..75fa4b94b --- a/src/GEOMUtils/GEOMUtils.cxx +++ b/src/GEOMUtils/GEOMUtils.cxx @@@ -147,116 -136,82 +147,76 @@@ namespac const Standard_Boolean isShell = (sh.ShapeType()==TopAbs_SHELL || sh.ShapeType()==TopAbs_FACE); - if( isShell || S->IsUPeriodic() ) { - // non solid case or any periodic surface (Mantis 22454). - double U1,U2,V1,V2; - // changes for 0020677: EDF 1219 GEOM: MinDistance gives 0 instead of 20.88 - //S->Bounds(U1,U2,V1,V2); changed by - ShapeAnalysis::GetFaceUVBounds(TopoDS::Face(theModifiedShape),U1,U2,V1,V2); - // end of changes for 020677 (dmv) - Handle(Geom_RectangularTrimmedSurface) TrS1 = - new Geom_RectangularTrimmedSurface(S,U1,(U1+U2)/2.,V1,V2); - Handle(Geom_RectangularTrimmedSurface) TrS2 = - new Geom_RectangularTrimmedSurface(S,(U1+U2)/2.,U2,V1,V2); + if ( !isShell && S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ) { + Handle(Geom_SphericalSurface) SS = Handle(Geom_SphericalSurface)::DownCast(S); + gp_Pnt PC = SS->Location(); BRep_Builder B; - TopoDS_Face F1,F2; - TopoDS_Shape aMShape; - - if (isShell) { - B.MakeCompound(TopoDS::Compound(aMShape)); - } else { - B.MakeShell(TopoDS::Shell(aMShape)); - } - - B.MakeFace(F1,TrS1,1.e-7); - B.Add(aMShape,F1); - B.MakeFace(F2,TrS2,1.e-7); - B.Add(aMShape,F2); - Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape; - - if (!isShell) { - // The original shape is a solid. - TopoDS_Solid aSolid; - - B.MakeSolid(aSolid); - B.Add(aSolid, aMShape); - aMShape = aSolid; - } - - sfs->Init(aMShape); - sfs->SetPrecision(1.e-6); - sfs->SetMaxTolerance(1.0); - sfs->Perform(); - theModifiedShape = sfs->Shape(); - isModified = Standard_True; + TopoDS_Vertex V; + B.MakeVertex(V,PC,1.e-7); + theModifiedShape = V; + theAddDist = SS->Radius(); + return Standard_True; } - else { - if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ) { - Handle(Geom_SphericalSurface) SS = Handle(Geom_SphericalSurface)::DownCast(S); - gp_Pnt PC = SS->Location(); - BRep_Builder B; - TopoDS_Vertex V; - B.MakeVertex(V,PC,1.e-7); - theModifiedShape = V; - theAddDist = SS->Radius(); - isModified = Standard_True; - } - else { - Handle(Geom_ToroidalSurface) TS = Handle(Geom_ToroidalSurface)::DownCast(S); - gp_Ax3 ax3 = TS->Position(); - Handle(Geom_Circle) C = new Geom_Circle(ax3.Ax2(),TS->MajorRadius()); - BRep_Builder B; - TopoDS_Edge E; - B.MakeEdge(E,C,1.e-7); - theModifiedShape = E; - theAddDist = TS->MinorRadius(); - isModified = Standard_True; - } + if ( !isShell && S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) { + Handle(Geom_ToroidalSurface) TS = Handle(Geom_ToroidalSurface)::DownCast(S); + gp_Ax3 ax3 = TS->Position(); + Handle(Geom_Circle) C = new Geom_Circle(ax3.Ax2(),TS->MajorRadius()); + BRep_Builder B; + TopoDS_Edge E; + B.MakeEdge(E,C,1.e-7); + theModifiedShape = E; + theAddDist = TS->MinorRadius(); + return Standard_True; } - } else { - theModifiedShape = theShape; + + // non solid case or any periodic surface (Mantis 22454). + double U1,U2,V1,V2; + // changes for 0020677: EDF 1219 GEOM: MinDistance gives 0 instead of 20.88 + //S->Bounds(U1,U2,V1,V2); changed by + ShapeAnalysis::GetFaceUVBounds(TopoDS::Face(theModifiedShape),U1,U2,V1,V2); + // end of changes for 020677 (dmv) + Handle(Geom_RectangularTrimmedSurface) TrS1 = + new Geom_RectangularTrimmedSurface(S,U1,(U1+U2)/2.,V1,V2); + Handle(Geom_RectangularTrimmedSurface) TrS2 = + new Geom_RectangularTrimmedSurface(S,(U1+U2)/2.,U2,V1,V2); + TopoDS_Shape aMShape; + + TopoDS_Face F1 = BRepBuilderAPI_MakeFace(TrS1, Precision::Confusion()); + TopoDS_Face F2 = BRepBuilderAPI_MakeFace(TrS2, Precision::Confusion()); + + if (isShell) { + BRep_Builder B; + B.MakeCompound(TopoDS::Compound(aMShape)); + B.Add(aMShape, F1); + B.Add(aMShape, F2); + } else { + // The original shape is a solid. + BRepBuilderAPI_Sewing aSewing (Precision::Confusion()*10.0); + aSewing.Add(F1); + aSewing.Add(F2); + aSewing.Perform(); + aMShape = aSewing.SewedShape(); + BRep_Builder B; + TopoDS_Solid aSolid; + B.MakeSolid(aSolid); + B.Add(aSolid, aMShape); + aMShape = aSolid; + } + + Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape; + sfs->Init(aMShape); + sfs->SetPrecision(1.e-6); + sfs->SetMaxTolerance(1.0); + sfs->Perform(); + theModifiedShape = sfs->Shape(); + return Standard_True; } } - else - theModifiedShape = theShape; - - return isModified; + + theModifiedShape = theShape; + return Standard_False; } - //======================================================================= - //function : ShapeToDouble - //purpose : used by CompareShapes::operator() - //======================================================================= - std::pair ShapeToDouble (const TopoDS_Shape& S, bool isOldSorting) - { - // Computing of CentreOfMass - gp_Pnt GPoint; - double Len; - - if (S.ShapeType() == TopAbs_VERTEX) { - GPoint = BRep_Tool::Pnt(TopoDS::Vertex(S)); - Len = (double)S.Orientation(); - } - else { - GProp_GProps GPr; - // BEGIN: fix for Mantis issue 0020842 - if (isOldSorting) { - BRepGProp::LinearProperties(S, GPr); - } - else { - if (S.ShapeType() == TopAbs_EDGE || S.ShapeType() == TopAbs_WIRE) { - BRepGProp::LinearProperties(S, GPr); - } - else if (S.ShapeType() == TopAbs_FACE || S.ShapeType() == TopAbs_SHELL) { - BRepGProp::SurfaceProperties(S, GPr); - } - else { - BRepGProp::VolumeProperties(S, GPr); - } - } - // END: fix for Mantis issue 0020842 - GPoint = GPr.CentreOfMass(); - Len = GPr.Mass(); - } - - double dMidXYZ = GPoint.X() * 999.0 + GPoint.Y() * 99.0 + GPoint.Z() * 0.9; - return std::make_pair(dMidXYZ, Len); - } - void parseWard( const GEOMUtils::LevelsList &theLevelList, std::string &treeStr ) { treeStr.append( "{" ); diff --cc src/GEOM_I/GEOM_IShapesOperations_i.cc index e7f4c7b90,1fa7f1fb9..2ff91518b --- a/src/GEOM_I/GEOM_IShapesOperations_i.cc +++ b/src/GEOM_I/GEOM_IShapesOperations_i.cc @@@ -1907,43 -2018,100 +2018,141 @@@ GEOM::ListOfLong* GEOM_IShapesOperation return aSeq._retn(); } + //============================================================================= + /*! + * ExtendEdge + */ + //============================================================================= + GEOM::GEOM_Object_ptr GEOM_IShapesOperations_i::ExtendEdge + (GEOM::GEOM_Object_ptr theEdge, + CORBA::Double theMin, + CORBA::Double theMax) + { + GEOM::GEOM_Object_var aGEOMObject; + + //Set a not done flag + GetOperations()->SetNotDone(); + + //Get the reference objects + Handle(GEOM_Object) anEdge = GetObjectImpl(theEdge); + + if (anEdge.IsNull()) { + return aGEOMObject._retn(); + } + + //Get Shapes in place of aShapeWhat + Handle(GEOM_Object) aNewEdge = + GetOperations()->ExtendEdge(anEdge, theMin, theMax); + + if (!GetOperations()->IsDone() || aNewEdge.IsNull()) { + return aGEOMObject._retn(); + } + + return GetObject(aNewEdge); + } + + //============================================================================= + /*! + * ExtendFace + */ + //============================================================================= + GEOM::GEOM_Object_ptr GEOM_IShapesOperations_i::ExtendFace + (GEOM::GEOM_Object_ptr theFace, + CORBA::Double theUMin, + CORBA::Double theUMax, + CORBA::Double theVMin, + CORBA::Double theVMax) + { + GEOM::GEOM_Object_var aGEOMObject; + + //Set a not done flag + GetOperations()->SetNotDone(); + + //Get the reference objects + Handle(GEOM_Object) aFace = GetObjectImpl(theFace); + + if (aFace.IsNull()) { + return aGEOMObject._retn(); + } + + //Get Shapes in place of aShapeWhat + Handle(GEOM_Object) aNewFace = + GetOperations()->ExtendFace(aFace, theUMin, theUMax, theVMin, theVMax); + + if (!GetOperations()->IsDone() || aNewFace.IsNull()) { + return aGEOMObject._retn(); + } + + return GetObject(aNewFace); + } + + //============================================================================= + /*! + * MakeSurfaceFromFace + */ + //============================================================================= + GEOM::GEOM_Object_ptr GEOM_IShapesOperations_i::MakeSurfaceFromFace + (GEOM::GEOM_Object_ptr theFace) + { + GEOM::GEOM_Object_var aGEOMObject; + + //Set a not done flag + GetOperations()->SetNotDone(); + + //Get the reference object + Handle(GEOM_Object) aFace = GetObjectImpl(theFace); + + if (aFace.IsNull()) { + return aGEOMObject._retn(); + } + + //Get Shapes in place of aShapeWhat + Handle(GEOM_Object) aNewFace = GetOperations()->MakeSurfaceFromFace(aFace); + + if (!GetOperations()->IsDone() || aNewFace.IsNull()) { + return aGEOMObject._retn(); + } + + return GetObject(aNewFace); + } ++ +//============================================================================= +/*! + * GetSubShapeEdgeSorted + */ +//============================================================================= +GEOM::ListOfGO* GEOM_IShapesOperations_i::GetSubShapeEdgeSorted + (GEOM::GEOM_Object_ptr theShape, + GEOM::GEOM_Object_ptr theStartPoint) +{ + GEOM::ListOfGO_var aSeq = new GEOM::ListOfGO; + + //Set a not done flag + GetOperations()->SetNotDone(); + + //Get the reference objects + Handle(GEOM_Object) aShape = GetObjectImpl(theShape); + Handle(GEOM_Object) aStartPoint = GetObjectImpl(theStartPoint); + + if (aShape.IsNull() || aStartPoint.IsNull()) { + return aSeq._retn(); + } + + //Get Shapes On Shape + Handle(TColStd_HSequenceOfTransient) aHSeq = + GetOperations()->GetSubShapeEdgeSorted(aShape, aStartPoint); + + if (!GetOperations()->IsDone() || aHSeq.IsNull()) + return aSeq._retn(); + + const Standard_Integer aLength = aHSeq->Length(); + Standard_Integer i; + + aSeq->length(aLength); + + for (i = 1; i <= aLength; i++) { + aSeq[i-1] = GetObject(Handle(GEOM_Object)::DownCast(aHSeq->Value(i))); + } + + return aSeq._retn(); +} diff --cc src/GEOM_I/GEOM_IShapesOperations_i.hh index 5baa75ce3,9d0dbb464..5c74ca2c1 --- a/src/GEOM_I/GEOM_IShapesOperations_i.hh +++ b/src/GEOM_I/GEOM_IShapesOperations_i.hh @@@ -271,9 -285,18 +285,21 @@@ class GEOM_I_EXPORT GEOM_IShapesOperati GEOM::ListOfLong* GetSameIDs (GEOM::GEOM_Object_ptr theShapeWhere, GEOM::GEOM_Object_ptr theShapeWhat); + GEOM::GEOM_Object_ptr ExtendEdge(GEOM::GEOM_Object_ptr theEdge, + CORBA::Double theMin, + CORBA::Double theMax); + + GEOM::GEOM_Object_ptr ExtendFace(GEOM::GEOM_Object_ptr theFace, + CORBA::Double theUMin, + CORBA::Double theUMax, + CORBA::Double theVMin, + CORBA::Double theVMax); + + GEOM::GEOM_Object_ptr MakeSurfaceFromFace(GEOM::GEOM_Object_ptr theFace); + + GEOM::ListOfGO* GetSubShapeEdgeSorted (GEOM::GEOM_Object_ptr theShape, + GEOM::GEOM_Object_ptr theStartPoint); + ::GEOMImpl_IShapesOperations* GetOperations() { return (::GEOMImpl_IShapesOperations*)GetImpl(); } }; diff --cc src/GEOM_SWIG/GEOM_TestAll.py index 46c79bc52,2fef6a4c5..85c7b8aff --- a/src/GEOM_SWIG/GEOM_TestAll.py +++ b/src/GEOM_SWIG/GEOM_TestAll.py @@@ -252,8 -265,11 +265,11 @@@ def TestAll (geompy, math) Position = geompy.MakePosition(Box, cs1, cs2) #(3 GEOM_Object)->GEOM_Object Position2 = geompy.PositionAlongPath(Box, Arc, 0.5, 1, 0) #(2 GEOM_Object, 1 Double, 2 Bool)->GEOM_Object Offset = geompy.MakeOffset(Box, 10.) #(GEOM_Object, Double)->GEOM_Object - Orientation = geompy.ChangeOrientation(Box) ProjOnWire = geompy.MakeProjectionOnWire(p0, Wire) + Orientation = geompy.ChangeOrientation(Box) + ExtEdge = geompy.ExtendEdge(Edge1, -0.3, 1.3) + ExtFace = geompy.ExtendFace(Face5, -0.3, 1.3, -0.1, 1.1) + Surface = geompy.MakeSurfaceFromFace(Face5) #IDList for Fillet/Chamfer prism_edges = geompy.ExtractShapes(Prism, geompy.ShapeType["EDGE"], True) diff --cc src/GEOM_SWIG/geomBuilder.py index be89ae1a3,b5d4c2406..fad3398cb mode 100644,100755..100755 --- a/src/GEOM_SWIG/geomBuilder.py +++ b/src/GEOM_SWIG/geomBuilder.py @@@ -6047,38 -6296,38 +6296,70 @@@ class geomBuilder(object, GEOM._objref_ self._autoPublish(ListObj, theName, "subshape") return ListObj + ## Explode a shape into edges sorted in a row from a starting point. + # @param theShape the shape to be exploded on edges. + # @param theStartPoint the starting point. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # @return List of GEOM.GEOM_Object that is actually an ordered list + # of edges sorted in a row from a starting point. + # + # @ref swig_GetSubShapeEdgeSorted "Example" + @ManageTransactions("ShapesOp") + def GetSubShapeEdgeSorted(self, theShape, theStartPoint, theName=None): + """ + Explode a shape into edges sorted in a row from a starting point. + + Parameters: + theShape the shape to be exploded on edges. + theStartPoint the starting point. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. + + Returns: + List of GEOM.GEOM_Object that is actually an ordered list + of edges sorted in a row from a starting point. + """ + # Example: see GEOM_TestAll.py + ListObj = self.ShapesOp.GetSubShapeEdgeSorted(theShape, theStartPoint) + RaiseIfFailed("GetSubShapeEdgeSorted", self.ShapesOp) + self._autoPublish(ListObj, theName, "SortedEdges") + return ListObj + + ## Check if the object is a sub-object of another GEOM object. + # @param aSubObject Checked sub-object (or its parent object, in case if + # \a theSubObjectIndex is non-zero). + # @param anObject An object that is checked for ownership (or its parent object, + # in case if \a theObjectIndex is non-zero). + # @param aSubObjectIndex When non-zero, specifies a sub-shape index that + # identifies a sub-object within its parent specified via \a theSubObject. + # @param anObjectIndex When non-zero, specifies a sub-shape index that + # identifies an object within its parent specified via \a theObject. + # @return TRUE, if the given object contains sub-object. + @ManageTransactions("ShapesOp") + def IsSubShapeBelongsTo(self, aSubObject, anObject, aSubObjectIndex = 0, anObjectIndex = 0): + """ + Check if the object is a sub-object of another GEOM object. + + Parameters: + aSubObject Checked sub-object (or its parent object, in case if + \a theSubObjectIndex is non-zero). + anObject An object that is checked for ownership (or its parent object, + in case if \a theObjectIndex is non-zero). + aSubObjectIndex When non-zero, specifies a sub-shape index that + identifies a sub-object within its parent specified via \a theSubObject. + anObjectIndex When non-zero, specifies a sub-shape index that + identifies an object within its parent specified via \a theObject. + + Returns + TRUE, if the given object contains sub-object. + """ + IsOk = self.ShapesOp.IsSubShapeBelongsTo(aSubObject, aSubObjectIndex, anObject, anObjectIndex) + RaiseIfFailed("IsSubShapeBelongsTo", self.ShapesOp) + return IsOk + # end of l4_decompose ## @} @@@ -11444,11 -11763,10 +11806,11 @@@ # @return TRUE, if the given shape is a compound of blocks. # If theCompound is not valid, prints all discovered errors. # - # @ref tui_measurement_tools_page "Example 1" + # @ref tui_check_compound_of_blocks_page "Example 1" # \n @ref swig_CheckCompoundOfBlocks "Example 2" @ManageTransactions("BlocksOp") - def CheckCompoundOfBlocks(self,theCompound): + def CheckCompoundOfBlocks(self,theCompound, theIsUseC1 = False, + theAngTolerance = 1.e-12): """ Check, if the compound of blocks is given. To be considered as a compound of blocks, the @@@ -11502,16 -11800,12 +11864,16 @@@ # @return A tuple of two GEOM_Objects. The first object is a group of all # non block solids (= not 6 faces, or with 6 faces, but with the # presence of non-quadrangular faces). The second object is a - # group of all non quadrangular faces. + # group of all non quadrangular faces (= faces with more then + # 1 wire or, if theIsUseC1 is set to True, faces + # with 1 wire with not 4 edges that do not form 4 bounds of + # C1 continuity). # - # @ref tui_measurement_tools_page "Example 1" + # @ref tui_get_non_blocks_page "Example 1" # \n @ref swig_GetNonBlocks "Example 2" @ManageTransactions("BlocksOp") - def GetNonBlocks (self, theShape, theName=None): + def GetNonBlocks (self, theShape, theIsUseC1 = False, + theAngTolerance = 1.e-12, theName=None): """ Retrieve all non blocks solids and faces from theShape. diff --cc src/RepairGUI/RepairGUI_LimitToleranceDlg.cxx index 0a59f0313,0b447d106..dc5e3fa09 --- a/src/RepairGUI/RepairGUI_LimitToleranceDlg.cxx +++ b/src/RepairGUI/RepairGUI_LimitToleranceDlg.cxx @@@ -325,7 -327,7 +327,6 @@@ bool RepairGUI_LimitToleranceDlg::onAcc bool aLocked = aStudy->GetProperties()->IsLocked(); if (aLocked) { -- MESSAGE("GEOMBase_Helper::onAccept - ActiveStudy is locked"); SUIT_MessageBox::warning(this, tr("WRN_WARNING"), tr("WRN_STUDY_LOCKED"), tr("BUT_OK")); return false; }