From 331cb10202da6733b5dd9b0c9dfda9bf173ba3b0 Mon Sep 17 00:00:00 2001 From: dcq Date: Wed, 3 Dec 2003 15:06:54 +0000 Subject: [PATCH] DCQ : Update with V1.3.0 --- bin/VERSION | 2 +- doc/html/INPUT/doxyfile | 10 +- doc/html/INPUT/sources/Application-About.png | Bin 7684 -> 19226 bytes doc/html/INPUT/sources/Application-About1.jpg | Bin 21548 -> 14327 bytes doc/html/INPUT/sources/application.gif | Bin 2584 -> 2602 bytes doc/html/INPUT/sources/application.jpg | Bin 4664 -> 792 bytes doc/html/INPUT/sources/bg_salomepro.gif | Bin 17294 -> 0 bytes doc/html/INPUT/sources/doxygen.css | 49 - doc/html/Makefile.in | 5 +- src/BasicGUI/BasicGUI_PointDlg.cxx | 10 +- src/GEOM/GEOM_Gen_i.cc | 55 +- src/GEOM/Makefile.in | 2 +- src/GEOMBase/GEOMBase.cxx | 19 +- src/GEOMClient/Makefile.in | 2 +- src/GEOMDS/Makefile.in | 2 +- src/GEOMFiltersSelection/Makefile.in | 2 +- src/GenerationGUI/GenerationGUI_PipeDlg.cxx | 11 +- src/OBJECT/GEOM_AISShape.cxx | 12 +- src/OBJECT/GEOM_Actor.cxx | 7 +- src/OBJECT/Makefile.in | 3 +- src/PARTITION/Makefile.in | 2 +- src/PARTITION/Partition_Inter2d.cdl | 21 +- src/PARTITION/Partition_Inter2d.cxx | 553 +++++--- src/PARTITION/Partition_Inter2d.hxx | 4 +- src/PARTITION/Partition_Inter3d.cdl | 15 +- src/PARTITION/Partition_Inter3d.cxx | 275 ++-- src/PARTITION/Partition_Loop2d.cxx | 689 ++++----- src/PARTITION/Partition_Spliter.cdl | 37 +- src/PARTITION/Partition_Spliter.cxx | 1248 +++++++++++------ src/PARTITION/Partition_Spliter.hxx | 34 +- 30 files changed, 1888 insertions(+), 1181 deletions(-) delete mode 100755 doc/html/INPUT/sources/bg_salomepro.gif delete mode 100755 doc/html/INPUT/sources/doxygen.css diff --git a/bin/VERSION b/bin/VERSION index f38a71b14..6156fe3ca 100755 --- a/bin/VERSION +++ b/bin/VERSION @@ -1 +1 @@ -THIS IS SALOME PRO - GEOM VERSION: 1.2 +THIS IS SALOME - GEOM VERSION: 1.3.0 diff --git a/doc/html/INPUT/doxyfile b/doc/html/INPUT/doxyfile index d6fd95ccc..90395f67f 100755 --- a/doc/html/INPUT/doxyfile +++ b/doc/html/INPUT/doxyfile @@ -3,7 +3,7 @@ #--------------------------------------------------------------------------- # General configuration options #--------------------------------------------------------------------------- -PROJECT_NAME = "SALOME PRO - GEOM - v.1.2" +PROJECT_NAME = "SALOME - GEOM - v.1.3.0" PROJECT_NUMBER = id#1.1 OUTPUT_DIRECTORY = ../ OUTPUT_LANGUAGE = English @@ -97,11 +97,11 @@ GENERATE_HTMLHELP = NO CHM_FILE = HHC_LOCATION = GENERATE_CHI = NO -BINARY_TOC = NO -TOC_EXPAND = NO -DISABLE_INDEX = NO +BINARY_TOC = YES +TOC_EXPAND = YES +DISABLE_INDEX = YES ENUM_VALUES_PER_LINE = 4 -GENERATE_TREEVIEW = NO +GENERATE_TREEVIEW = YES TREEVIEW_WIDTH = 250 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output diff --git a/doc/html/INPUT/sources/Application-About.png b/doc/html/INPUT/sources/Application-About.png index 80e0bcb063acf425fa1001d39beea368bb4497a3..7b58330d50856e28562e8f9ed80dae72d6e6dda3 100755 GIT binary patch literal 19226 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

5r3>=?gKv-6#gF2kVYm^Euk4pDx%bDo{L~m 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 diff --git a/doc/html/INPUT/sources/Application-About1.jpg b/doc/html/INPUT/sources/Application-About1.jpg index b8f2cfb6da8aa2f60922b1c60f642ce9e1eebab5..cf7ab8ba025d6bd9212f8bd5681e77d1aaef8e4f 100755 GIT binary patch literal 14327 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 Ao&W#< literal 21548 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 diff --git a/doc/html/INPUT/sources/application.gif b/doc/html/INPUT/sources/application.gif index 10da488d2dcf2a063029d868686e1882e45487ab..0b05d5c18ee88779d283508781836e2b151f606f 100644 GIT binary patch literal 2602 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 diff --git a/doc/html/INPUT/sources/application.jpg b/doc/html/INPUT/sources/application.jpg index 6d3b6a0a8c281dca8747fdd34b4d4de0f737c4a3..a6979ab9999552ccb91a0358f75103b09db5246c 100755 GIT binary patch literal 792 zcmex=LJ%Z3brs z4mLJ+HdYRHc6Lrq4lW)MULJ049!Vi#ei2zIc{y1r85so?J#_^o9c39A4RcK$149!N z6M1z@TMHu_J!2CikRgnmoSZz|JQBRT5=M$Libf=Z{|6WZIT%D3%$OOK7?=bZnFSgD zA7PMUU}Rthc>@7h+1MFbn1ONz0t}4I%#5t;OzcouMkZz!23A2KHbq0nKw(j(pu~w6 z3mZjLjGdA<9t7%;U}RuoMwkR-0lADUKp6!=1|~)pMph(AMnRxyib95giG>^g-(uil z25J^$7G$tz*b}$dob931la92ii?S2$h#I_dt2w(?+0U=MwPfirm!)r|%QL=xciqQ* zvhOkDlnJl1?mV9H$SWkchmTWj{f7p#7YBO!PTF5sw@#T`LbrdbWo*ZV_O$5xlkGCE z^PPVyNw8xApK>WbnDiuj&ts=vwm~?+7XwjY*R$0pI#j4 zw{W$hO=am?)v#v=Y$tVvo>o`d(V^*ixTv>ZZDX3QFXcToO*@xTm3CIa<27tEIc#! zWx8M8?h`8_qqEtJR5Yui4EIMazr(xByvXzMzf0?$2CWRax^UXZS*s@%RlmEiXqi&U zv6PDAY{#9wTC9VfKD+s&O=r4T6dx~>x9e7&gdYvo8^51ls#!DPMamTK%`aPJ6?q?+ z%yVDxb^Z406Q4}q)Ma`pwL@9=KH2nE%g+j0$PN+6w!7WCc0S)@-fuIzZ#hkAx*44E xJV2p&e;fZ&&B#yDAuHbPYtLW(<#g|%_lh@oH9azfmdriy#cs<|Z3p)MHvxBP8gc*t literal 4664 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 XJGIWw3pUly>lLb4Wn_sb)B64kGG>E? diff --git a/doc/html/INPUT/sources/bg_salomepro.gif b/doc/html/INPUT/sources/bg_salomepro.gif deleted file mode 100755 index 677b70468f798fe4fbc20fac3d706e61179ff12b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17294 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 doxyfile1; \ + sed 's|../../../share/salome|$(root_srcdir)|' doxyfile > doxyfile1; \ mv -f doxyfile1 doxyfile; \ $(doxygen) ./doxyfile; \ cd ..; \ - cp -f $(srcdir)/INPUT/sources/doxygen.css ./html/doxygen.css + cp -fr $(srcdir)/INPUT/sources/static/*.* ./html/ cp -fr $(srcdir)/INPUT/sources/ html/ cp -fr $(srcdir)/INPUT/HTML/ html/ diff --git a/src/BasicGUI/BasicGUI_PointDlg.cxx b/src/BasicGUI/BasicGUI_PointDlg.cxx index e219f498f..51b287dd2 100644 --- a/src/BasicGUI/BasicGUI_PointDlg.cxx +++ b/src/BasicGUI/BasicGUI_PointDlg.cxx @@ -34,8 +34,12 @@ using namespace std; #include #include -#include #include +#if OCC_VERSION_MAJOR >= 5 +#include +#else +#include +#endif //================================================================================= // class : BasicGUI_PointDlg() @@ -518,7 +522,11 @@ void BasicGUI_PointDlg::ValueChangedInSpinBox(double newValue) //================================================================================= bool BasicGUI_PointDlg::CalculateVertexOnCurve(const TopoDS_Edge& anEdge, const Standard_Real aParameter, TopoDS_Shape& resultVertex) { +#if OCC_VERSION_MAJOR >= 5 + if(anEdge.IsNull() || !BRepAlgo::IsValid(anEdge)) +#else if(anEdge.IsNull() || !BRepAlgoAPI::IsValid(anEdge)) +#endif return false; Standard_Real first, last; diff --git a/src/GEOM/GEOM_Gen_i.cc b/src/GEOM/GEOM_Gen_i.cc index e7151d1b8..4ec4f1322 100644 --- a/src/GEOM/GEOM_Gen_i.cc +++ b/src/GEOM/GEOM_Gen_i.cc @@ -55,7 +55,11 @@ using namespace std; #include #include +#if OCC_VERSION_MAJOR >= 5 +#include +#else #include +#endif #include #include #include @@ -150,6 +154,14 @@ using namespace std; #include CORBA_SERVER_HEADER(SALOMEDS_Attributes) +Standard_EXPORT static Standard_Boolean IsValid(const TopoDS_Shape& S) { +#if OCC_VERSION_MAJOR >= 5 + return BRepAlgo::IsValid(S); +#else + return BRepAlgoAPI::IsValid(S); +#endif +} + //============================================================================ // function : GEOM_Gen_i() // purpose : constructor to be called for servant creation. @@ -761,8 +773,13 @@ const char* GEOM_Gen_i::GetStringFromIOR(GEOM::GEOM_Shape_var shapeIOR) { // purpose : returns a 'GEOM::GEOM_Shape_var' from a string representing it //================================================================================= GEOM::GEOM_Shape_ptr GEOM_Gen_i::GetIORFromString(const char* stringIOR) { - GEOM::GEOM_Shape_var shapeIOR = GEOM::GEOM_Shape::_narrow(_orb->string_to_object(stringIOR)) ; - return shapeIOR._retn(); + GEOM::GEOM_Shape_var shapeIOR; + if(strcmp(stringIOR,"") != 0){ + CORBA::Object_var anObject = _orb->string_to_object(stringIOR); + if(!CORBA::is_nil(anObject)) + shapeIOR = GEOM::GEOM_Shape::_narrow(anObject.in()) ; + } + return shapeIOR._retn() ; } @@ -1446,7 +1463,7 @@ GEOM::GEOM_Shape_ptr GEOM_Gen_i::SuppressHolesInFaceOrShell( GEOM::GEOM_Shape_pt THROW_SALOME_CORBA_EXCEPTION("in GEOM_Gen_i::SuppressHolesInFace : no holes selected", SALOME::BAD_PARAM); const TopoDS_Shape tds = GetTopoShape(shapeFaceShell) ; - if( tds.IsNull() || !BRepAlgoAPI::IsValid(tds) ) + if( tds.IsNull() || !IsValid(tds) ) THROW_SALOME_CORBA_EXCEPTION("in GEOM_Gen_i::SuppressHolesInFace() : non valid main argument", SALOME::BAD_PARAM); /* Create a map of wires/holes to suppress */ @@ -1552,7 +1569,7 @@ bool GEOM_Gen_i::RebuildFaceRemovingHoles( const TopoDS_Face& aFace, { /* Get the outer wire of the face 'aFace' */ TopoDS_Wire outW = BRepTools::OuterWire( aFace ) ; - if( outW.IsNull() || !BRepAlgoAPI::IsValid(outW) ) + if( outW.IsNull() || !IsValid(outW) ) THROW_SALOME_CORBA_EXCEPTION("in GEOM_Gen_i::SuppressHolesInFace : bad outer wire of 'aFace'", SALOME::BAD_PARAM); /* Rebuild a face avoiding holes in the map 'mapHoles' */ @@ -1612,7 +1629,7 @@ GEOM::GEOM_Shape_ptr GEOM_Gen_i::SuppressHole( GEOM::GEOM_Shape_ptr shape, /* Retrieve 'aShape' the initial main shape selection */ const TopoDS_Shape aShape = GetTopoShape(shape); - if( !BRepAlgoAPI::IsValid(aShape) ) + if( !IsValid(aShape) ) THROW_SALOME_CORBA_EXCEPTION("in GEOM_Gen_i::SuppressHole() : non valid main shape", SALOME::BAD_PARAM); if( ListIdFace.length() != 1 || ListIdWire.length() != 1 ) @@ -1625,7 +1642,7 @@ GEOM::GEOM_Shape_ptr GEOM_Gen_i::SuppressHole( GEOM::GEOM_Shape_ptr shape, else { aFace = TopoDS::Face(tmp) ; } - if( !BRepAlgoAPI::IsValid(aFace) ) + if( !IsValid(aFace) ) THROW_SALOME_CORBA_EXCEPTION("in GEOM_Gen_i::SuppressHole() : face shape not valid", SALOME::BAD_PARAM); /* Retrieve 'aWire' selection : Warning : index of wire refers to the face ! */ @@ -1636,12 +1653,12 @@ GEOM::GEOM_Shape_ptr GEOM_Gen_i::SuppressHole( GEOM::GEOM_Shape_ptr shape, else { aWire = TopoDS::Wire(aTmp) ; } - if( !BRepAlgoAPI::IsValid(aWire) ) + if( !IsValid(aWire) ) THROW_SALOME_CORBA_EXCEPTION("in GEOM_Gen_i::SuppressHole() : bad wire" , SALOME::BAD_PARAM); /* Get the outer wire of aFace */ TopoDS_Wire outerW = BRepTools::OuterWire( aFace ) ; - if( outerW.IsNull() || !BRepAlgoAPI::IsValid(outerW) ) + if( outerW.IsNull() || !IsValid(outerW) ) THROW_SALOME_CORBA_EXCEPTION("in GEOM_Gen_i::SuppressHole() : bad outer wire", SALOME::BAD_PARAM); /* Test bad user selection aWire */ @@ -1655,7 +1672,7 @@ GEOM::GEOM_Shape_ptr GEOM_Gen_i::SuppressHole( GEOM::GEOM_Shape_ptr shape, } else { TopoDS_Shape aTemp ; - if( !GetShapeFromIndex( aShape, TopAbs_FACE, ListIdEndFace[0], aTemp ) || tmp.IsNull() || !BRepAlgoAPI::IsValid(aTemp) ) + if( !GetShapeFromIndex( aShape, TopAbs_FACE, ListIdEndFace[0], aTemp ) || tmp.IsNull() || !IsValid(aTemp) ) THROW_SALOME_CORBA_EXCEPTION("in GEOM_Gen_i::SuppressHole() : non valid endFace", SALOME::BAD_PARAM); /* Test if 'endFace' as at least one hole */ @@ -1665,7 +1682,7 @@ GEOM::GEOM_Shape_ptr GEOM_Gen_i::SuppressHole( GEOM::GEOM_Shape_ptr shape, int nbWires = 0 ; for( fExp.Init(endFace, TopAbs_WIRE); fExp.More(); fExp.Next() ) { TopoDS_Wire W = TopoDS::Wire( fExp.Current() ) ; - if( !W.IsNull() && BRepAlgoAPI::IsValid(W) ) + if( !W.IsNull() && IsValid(W) ) nbWires++ ; } if(nbWires > 1) @@ -1816,7 +1833,7 @@ bool GEOM_Gen_i::BuildShellWithFaceCompound( const TopoDS_Compound Comp, int i = 0 ; for( ex.Init( Comp, TopAbs_FACE); ex.More(); ex.Next() ) { TopoDS_Face F = TopoDS::Face( ex.Current() ) ; - if( !BRepAlgoAPI::IsValid(F) ) { + if( !IsValid(F) ) { return false ; } B.AddShellFace( resultShell, F ) ; @@ -1847,7 +1864,7 @@ bool GEOM_Gen_i::FindCompareWireHoleOnFace( const TopoDS_Face& F, /* Get the outer wire of aFace */ TopoDS_Wire outerW = BRepTools::OuterWire(F) ; - if( outerW.IsNull() || !BRepAlgoAPI::IsValid(outerW) ) { + if( outerW.IsNull() || !IsValid(outerW) ) { return false ; } @@ -2354,7 +2371,7 @@ GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakeBoolean(GEOM::GEOM_Shape_ptr shape1, } /* We test the validity of resulting shape */ - if( !BRepAlgoAPI::IsValid(shape) ) { + if( !IsValid(shape) ) { THROW_SALOME_CORBA_EXCEPTION("Boolean aborted : non valid shape result", SALOME::BAD_PARAM); } @@ -2408,7 +2425,7 @@ GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakeFuse(GEOM::GEOM_Shape_ptr shape1, } /* We test the validity of resulting shape */ - if( !BRepAlgoAPI::IsValid(shape) ) { + if( !IsValid(shape) ) { THROW_SALOME_CORBA_EXCEPTION("Fuse aborted : non valid shape result", SALOME::BAD_PARAM); } @@ -2860,7 +2877,7 @@ throw (SALOME::SALOME_Exception) tds = PS.Shape(); - if( !BRepAlgoAPI::IsValid(tds) ) { + if( !IsValid(tds) ) { //MESSAGE ( "In Partition: non valid shape result" ); THROW_SALOME_CORBA_EXCEPTION("Partition aborted : non valid shape result", SALOME::BAD_PARAM); } @@ -3004,7 +3021,7 @@ GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakeFilling(GEOM::GEOM_Shape_ptr myShape, } /* We test the validity of resulting shape */ - if( !BRepAlgoAPI::IsValid(tds) ) { + if( !IsValid(tds) ) { THROW_SALOME_CORBA_EXCEPTION("Filling aborted : non valid shape result", SALOME::BAD_PARAM); } else { @@ -3296,7 +3313,7 @@ GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakeSewing( const GEOM::GEOM_Gen::ListOfIOR& Li aMethod.Perform() ; tds = aMethod.SewedShape() ; - if( !BRepAlgoAPI::IsValid(tds) ) { + if( !IsValid(tds) ) { THROW_SALOME_CORBA_EXCEPTION("Make Sewing aborted : non valid shape", SALOME::BAD_PARAM); } if( tds.IsNull() ) { @@ -3335,7 +3352,7 @@ GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakeSewingShape( GEOM::GEOM_Shape_ptr aShape, aMethod.Perform() ; tds = aMethod.SewedShape() ; - if( !BRepAlgoAPI::IsValid(tds) ) { + if( !IsValid(tds) ) { THROW_SALOME_CORBA_EXCEPTION("Make Sewing aborted : non valid shape", SALOME::BAD_PARAM); } } @@ -4476,7 +4493,7 @@ GEOM::GEOM_Shape_ptr GEOM_Gen_i::MakePipe( GEOM::GEOM_Shape_ptr pathShape, THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::MakePipe", SALOME::BAD_PARAM); } - if ( !BRepAlgoAPI::IsValid(tds) ) { + if ( !IsValid(tds) ) { THROW_SALOME_CORBA_EXCEPTION("MakePipe aborted : non valid shape result", SALOME::BAD_PARAM); } else { diff --git a/src/GEOM/Makefile.in b/src/GEOM/Makefile.in index 800efcb6e..738e9ae64 100644 --- a/src/GEOM/Makefile.in +++ b/src/GEOM/Makefile.in @@ -51,7 +51,7 @@ EXPORT_HEADERS = # additionnal information to compil and link file CPPFLAGS += $(OCC_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome CXXFLAGS += $(OCC_CXXFLAGS) -I${KERNEL_ROOT_DIR}/include/salome -LDFLAGS += $(OCC_KERNEL_LIBS) $(OCC_MODELER_LIBS) $(OCC_DATAEXCHANGE_LIBS) -lGEOMDS -lSalomeDS -lSalomeNS -lSalomeContainer -lGEOMPartition -lGEOMArchimede -L${KERNEL_ROOT_DIR}/lib/salome +LDFLAGS += -lGEOMDS -lTOOLSDS -lSalomeNS -lSalomeContainer -lGEOMPartition -lGEOMArchimede $(CAS_LDPATH) -lTKIGES -lTKSTEP -lTKFillet -lTKOffset -L${KERNEL_ROOT_DIR}/lib/salome # additional file to be cleaned MOSTLYCLEAN = diff --git a/src/GEOMBase/GEOMBase.cxx b/src/GEOMBase/GEOMBase.cxx index cf1f54375..f513c6394 100644 --- a/src/GEOMBase/GEOMBase.cxx +++ b/src/GEOMBase/GEOMBase.cxx @@ -1151,9 +1151,9 @@ Handle(GEOM_AISShape) GEOMBase::ConvertIOinGEOMAISShape(const Handle(SALOME_Inte //======================================================================= GEOM::GEOM_Shape_ptr GEOMBase::ConvertIOinGEOMShape(const Handle(SALOME_InteractiveObject)& IO, Standard_Boolean& testResult) { - GEOM::GEOM_Shape_ptr aShape; + GEOM::GEOM_Shape_var aShape; testResult = false; - + /* case SObject */ if(IO->hasEntry()) { SALOMEDS::Study_var aStudy = QAD_Application::getDesktop()->getActiveStudy()->getStudyDocument(); @@ -1164,8 +1164,9 @@ GEOM::GEOM_Shape_ptr GEOMBase::ConvertIOinGEOMShape(const Handle(SALOME_Interact if(obj->FindAttribute(anAttr, "AttributeIOR")) { anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); aShape = myGeom->GetIORFromString(anIOR->Value()); - testResult = true; - return aShape; + if(!CORBA::is_nil(aShape)) + testResult = true; + return aShape._retn(); } } } @@ -1173,11 +1174,13 @@ GEOM::GEOM_Shape_ptr GEOMBase::ConvertIOinGEOMShape(const Handle(SALOME_Interact if(IO->IsInstance(STANDARD_TYPE(GEOM_InteractiveObject))) { Handle(GEOM_InteractiveObject) GIObject = Handle(GEOM_InteractiveObject)::DownCast(IO); Standard_CString ior = GIObject->getIOR(); - testResult = true; + aShape = myGeom->GetIORFromString(ior); - return aShape; - } - return aShape; + if(!CORBA::is_nil(aShape)) + testResult = true; + return aShape._retn(); + } + return aShape._retn(); } diff --git a/src/GEOMClient/Makefile.in b/src/GEOMClient/Makefile.in index aed4bccb6..32db3e220 100644 --- a/src/GEOMClient/Makefile.in +++ b/src/GEOMClient/Makefile.in @@ -53,7 +53,7 @@ BIN_SERVER_IDL = # additionnal information to compil and link file CPPFLAGS += $(OCC_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome CXXFLAGS += $(OCC_CXXFLAGS) -I${KERNEL_ROOT_DIR}/include/salome -LDFLAGS += $(OCC_KERNEL_LIBS) $(OCC_MODELER_LIBS) -L${KERNEL_ROOT_DIR}/lib/salome +LDFLAGS += $(CAS_LDPATH) -lTKTopAlgo -L${KERNEL_ROOT_DIR}/lib/salome @CONCLUDE@ diff --git a/src/GEOMDS/Makefile.in b/src/GEOMDS/Makefile.in index 27834c28b..b58244fd1 100644 --- a/src/GEOMDS/Makefile.in +++ b/src/GEOMDS/Makefile.in @@ -63,7 +63,7 @@ EXPORT_HEADERS= GEOMDS_Application.hxx \ # additionnal information to compil and link file CPPFLAGS += $(OCC_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome CXXFLAGS += $(OCC_CXXFLAGS) -I${KERNEL_ROOT_DIR}/include/salome -LDFLAGS += $(OCC_KERNEL_LIBS) $(OCC_OCAF_LIBS) +LDFLAGS += $(CAS_LDPATH) -lTKCAF # additional file to be cleaned MOSTLYCLEAN = diff --git a/src/GEOMFiltersSelection/Makefile.in b/src/GEOMFiltersSelection/Makefile.in index 0a4ac65f6..851695357 100644 --- a/src/GEOMFiltersSelection/Makefile.in +++ b/src/GEOMFiltersSelection/Makefile.in @@ -54,7 +54,7 @@ EXPORT_HEADERS= GEOM_ShapeTypeFilter.hxx \ # additionnal information to compil and link file CPPFLAGS += $(OCC_INCLUDES) $(QT_INCLUDES) $(PYTHON_INCLUDES) $(VTK_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome CXXFLAGS += $(OCC_CXXFLAGS) -I${KERNEL_ROOT_DIR}/include/salome -LDFLAGS += $(OCC_KERNEL_LIBS) -L${KERNEL_ROOT_DIR}/lib/salome +LDFLAGS += -lSalomeGUI -L${KERNEL_ROOT_DIR}/lib/salome # additional file to be cleaned MOSTLYCLEAN = diff --git a/src/GenerationGUI/GenerationGUI_PipeDlg.cxx b/src/GenerationGUI/GenerationGUI_PipeDlg.cxx index ba30db7e1..dae7c23f6 100644 --- a/src/GenerationGUI/GenerationGUI_PipeDlg.cxx +++ b/src/GenerationGUI/GenerationGUI_PipeDlg.cxx @@ -32,7 +32,11 @@ using namespace std; #include #include #include +#if OCC_VERSION_MAJOR >= 5 +#include +#else #include +#endif //================================================================================= // class : GenerationGUI_PipeDlg() @@ -287,7 +291,12 @@ void GenerationGUI_PipeDlg::MakePipeSimulationAndDisplay() } TopoDS_Shape tds = BRepOffsetAPI_MakePipe(aWire,myShape1); - if(BRepAlgoAPI::IsValid(tds)) { +#if OCC_VERSION_MAJOR >= 5 + if(BRepAlgo::IsValid(tds)) +#else + if(BRepAlgoAPI::IsValid(tds)) +#endif + { //Draw Pipe mySimulationTopoDs = tds; myGeomBase->DisplaySimulationShape(mySimulationTopoDs); diff --git a/src/OBJECT/GEOM_AISShape.cxx b/src/OBJECT/GEOM_AISShape.cxx index 93cbeaa78..e87917f5e 100644 --- a/src/OBJECT/GEOM_AISShape.cxx +++ b/src/OBJECT/GEOM_AISShape.cxx @@ -101,9 +101,17 @@ void GEOM_AISShape::Compute(const Handle(PrsMgr_PresentationManager3d)& aPresent case StdSelect_DM_Shading: { myDrawer->ShadingAspect()->Aspect()->SetDistinguishOn(); - myDrawer->ShadingAspect()->Aspect()->SetFrontMaterial(Graphic3d_NOM_BRASS); + + Graphic3d_MaterialAspect aMatAspect; + aMatAspect.SetAmbient( 1 ); + aMatAspect.SetDiffuse( 0 ); + aMatAspect.SetEmissive( 0 ); + aMatAspect.SetShininess(1 ); + aMatAspect.SetSpecular( 0 ); + + myDrawer->ShadingAspect()->Aspect()->SetFrontMaterial(aMatAspect); myDrawer->ShadingAspect()->Aspect()->SetBackMaterial(Graphic3d_NOM_JADE); - + Graphic3d_MaterialAspect FMat = myDrawer->ShadingAspect()->Aspect()->FrontMaterial(); Graphic3d_MaterialAspect BMat = myDrawer->ShadingAspect()->Aspect()->BackMaterial(); FMat.SetTransparency(myTransparency); BMat.SetTransparency(myTransparency); diff --git a/src/OBJECT/GEOM_Actor.cxx b/src/OBJECT/GEOM_Actor.cxx index 534445ae1..333086ad0 100644 --- a/src/OBJECT/GEOM_Actor.cxx +++ b/src/OBJECT/GEOM_Actor.cxx @@ -305,11 +305,8 @@ void GEOM_Actor::Render(vtkRenderer *ren, vtkMapper *Mapper) aMatrix->Delete(); } else this->Device->Render(ren, this->Mapper); - - if(myDisplayMode >= 1) - this->EstimatedRenderTime = ShadingMapper->GetTimeToDraw(); - else - this->EstimatedRenderTime = WireframeMapper->GetTimeToDraw(); + if(WireframeMapper!=NULL) this->EstimatedRenderTime = WireframeMapper->GetTimeToDraw(); + else if(ShadingMapper!=NULL) this->EstimatedRenderTime = ShadingMapper->GetTimeToDraw(); } // SubShape diff --git a/src/OBJECT/Makefile.in b/src/OBJECT/Makefile.in index c3978f5ed..154c41d95 100644 --- a/src/OBJECT/Makefile.in +++ b/src/OBJECT/Makefile.in @@ -57,8 +57,7 @@ BIN_SRC = CPPFLAGS+=$(QT_INCLUDES) $(PYTHON_INCLUDES) $(OCC_INCLUDES) $(VTK_INCLUDES) $(OGL_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome CXXFLAGS += -I${KERNEL_ROOT_DIR}/include/salome -LDFLAGS+=$(QT_MT_LIBS) $(OCC_KERNEL_LIBS) $(OCC_VIEWER_LIBS) $(VTK_LIBS) $(OGL_LIBS) $(PYTHON_LIBS) -lSalomeObject -L${KERNEL_ROOT_DIR}/lib/salome - +LDFLAGS+=$(QT_MT_LIBS) $(VTK_LIBS) $(OGL_LIBS) $(PYTHON_LIBS) -lSalomeObject -L${KERNEL_ROOT_DIR}/lib/salome %_moc.cxx: %.h $(MOC) $< -o $@ diff --git a/src/PARTITION/Makefile.in b/src/PARTITION/Makefile.in index a7a9fa34b..76de606eb 100644 --- a/src/PARTITION/Makefile.in +++ b/src/PARTITION/Makefile.in @@ -55,7 +55,7 @@ EXPORT_IDLS= CPPFLAGS += $(OCC_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome CXXFLAGS += $(OCC_CXXFLAGS) -I${KERNEL_ROOT_DIR}/include/salome -LDFLAGS += $(OCC_KERNEL_LIBS) $(OCC_MODELER_LIBS) -L${KERNEL_ROOT_DIR}/lib/salome +LDFLAGS += $(CAS_LDPATH) -lTKBool -L${KERNEL_ROOT_DIR}/lib/salome %_moc.cxx: %.h $(MOC) $< -o $@ diff --git a/src/PARTITION/Partition_Inter2d.cdl b/src/PARTITION/Partition_Inter2d.cdl index a3a4d15d2..1dcaa264b 100644 --- a/src/PARTITION/Partition_Inter2d.cdl +++ b/src/PARTITION/Partition_Inter2d.cdl @@ -62,13 +62,30 @@ is AddVonE(myclass; V : Vertex from TopoDS; E1,E2 : Edge from TopoDS; - AsDes : mutable AsDes from BRepAlgo) + AsDes : mutable AsDes from BRepAlgo; + F: Face from TopoDS) returns Vertex from TopoDS; ---Purpose: Put V in AsDes as intersection of E1 and E2. -- Check that vertex equal to V already exists on one -- of edges, in such a case, V is not added but -- existing vertex is updated to be on E1 and E2 and - -- is returned insead of V. + -- is returned insead of V. + -- Optional F is a face E1 and E2 are on. If F is + -- provided, it is used to find new vertices on E1 + -- and E2 resulting from intersection of new edges on + -- the two other faces the F interferes with and + -- through which E1 and E2 pass too. This helps to + -- avoid small edges. + + + GetTolerance(myclass; theV : Vertex from TopoDS; + theU : Real from Standard; + theE : Edge from TopoDS; + theAsDes : AsDes from BRepAlgo) + returns Real from Standard; + ---Purpose: Returns tolerance theV must have atfer its + -- addition to theE with theU parameter. theAsDes is + -- used to find pcurves of theE end Inter2d; diff --git a/src/PARTITION/Partition_Inter2d.cxx b/src/PARTITION/Partition_Inter2d.cxx index e15bf24e3..54b25e6e9 100644 --- a/src/PARTITION/Partition_Inter2d.cxx +++ b/src/PARTITION/Partition_Inter2d.cxx @@ -1,23 +1,23 @@ // GEOM PARTITION : partition algorithm // // Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org // // // @@ -31,30 +31,26 @@ using namespace std; #include "utilities.h" -#include -#include - +#include #include - +#include #include #include -#include -#include - -#include -#include -#include -#include +#include +#include +#include +#include +#include #include #include -#include -#include #include -#include +#include #include - -#include -#include +#include +#include +#include +#include +#include #ifdef DEB static Standard_Boolean TestEdges = 0; @@ -63,21 +59,110 @@ static Standard_Integer NbE2d = 0; #endif //======================================================================= -//function : StorePart2d -//purpose : +//function : getOtherShape +//purpose : +//======================================================================= + +static TopoDS_Shape getOtherShape(const TopoDS_Shape& theS, + const TopTools_ListOfShape& theSList) +{ + TopTools_ListIteratorOfListOfShape anIt( theSList ); + for ( ; anIt.More(); anIt.Next() ) + if (!theS.IsSame( anIt.Value() )) + return anIt.Value(); + + return TopoDS_Shape(); +} + +//======================================================================= +//function : findVOnE +//purpose : on theE, find a vertex close to theV, such that an edge +// passing through it is an itersection of theF1 and theF2. +// theE intersects theE2 at theV +//======================================================================= + +static Standard_Boolean findVOnE(const TopoDS_Vertex & theV, + const TopoDS_Edge& theE, + const TopoDS_Edge& theE2, + const TopoDS_Shape& theF1, + const TopoDS_Shape& theF2, + const Handle(BRepAlgo_AsDes)& theAsDes, + TopoDS_Vertex & theFoundV) +{ + Standard_Real MinDist2 = ::RealLast(); + gp_Pnt P; + + // check all vertices on theE + const TopTools_ListOfShape& aVList = theAsDes->Descendant( theE ); + TopTools_ListIteratorOfListOfShape anIt( aVList ); + if (anIt.More()) + P = BRep_Tool::Pnt( theV ); + for ( ; anIt.More(); anIt.Next() ) + { + // check by distance + TopoDS_Vertex & V = TopoDS::Vertex( anIt.Value() ); + Standard_Real dist2 = P.SquareDistance( BRep_Tool::Pnt( V )); + if (dist2 < MinDist2) + MinDist2 = dist2; + else + continue; + + // V is a candidate if among edges passing through V there is one + // which is an intersection of theF1 and theF2 + TopTools_ListIteratorOfListOfShape anEIt( theAsDes->Ascendant( V )); + Standard_Boolean isOk = Standard_False; + for ( ; !isOk && anEIt.More(); anEIt.Next() ) + { + const TopoDS_Shape & E2 = anEIt.Value(); + if ( theE2.IsSame( E2 )) + continue; + const TopTools_ListOfShape & aFList = theAsDes->Ascendant( E2 ); + if (aFList.IsEmpty()) + continue; + if ( theF1.IsSame( aFList.First() )) + isOk = theF2.IsSame( aFList.Last() ); + else + isOk = theF2.IsSame( aFList.First() ) && theF1.IsSame( aFList.Last() ); + } + if (isOk) + theFoundV = V; + } + + if (theFoundV.IsNull()) + return Standard_False; + + // check that MinDist2 is not too large + Standard_Real f, l; + TopLoc_Location L; + Handle(Geom_Curve) aCurve = BRep_Tool::Curve( theE, L, f, l ); + gp_Pnt P1 = aCurve->Value( f ); + gp_Pnt P2 = aCurve->Value( 0.3 * f + 0.7 * l ); + //gp_Pnt P2 = aCurve->Value( 0.5 * ( f + l )); + if (MinDist2 > P1.SquareDistance( P2 )) + return Standard_False; + +#ifdef DEB + cout << "findVOnE: found MinDist = " << sqrt (MinDist2) << endl; +#endif + + return Standard_True; +} + +//======================================================================= +//function : AddVonE +//purpose : Put V in AsDes as intersection of E1 and E2. +// Check that vertex equal to V already exists on one +// of edges, in such a case, V is not added but +// existing vertex is updated to be on E1 and E2 and +// is returned insead of V. //======================================================================= -// static void StorePart2d (const TopoDS_Edge& E1, -// const TopoDS_Edge& E2, -// TopTools_ListOfShape& LV1, -// TopTools_ListOfShape& LV2, -// Handle(BRepAlgo_AsDes) AsDes, -// Standard_Real Tol) TopoDS_Vertex Partition_Inter2d::AddVonE(const TopoDS_Vertex& theV, - const TopoDS_Edge& E1, - const TopoDS_Edge& E2, - const Handle(BRepAlgo_AsDes)& AsDes) - + const TopoDS_Edge& E1, + const TopoDS_Edge& E2, + const Handle(BRepAlgo_AsDes)& AsDes, + const TopoDS_Face& theF) + { //------------------------------------------------------------- // test if the points of intersection already exist. If not, @@ -86,119 +171,128 @@ TopoDS_Vertex Partition_Inter2d::AddVonE(const TopoDS_Vertex& theV, //------------------------------------------------------------- const TopTools_ListOfShape& VOnE1 = AsDes->Descendant(E1); const TopTools_ListOfShape& VOnE2 = AsDes->Descendant(E2); - TopTools_ListOfShape NewVOnE1; - TopTools_ListOfShape NewVOnE2; gp_Pnt P1,P2; TopoDS_Vertex V1,V2; - TopTools_ListIteratorOfListOfShape it, itLV1, itLV2; + TopTools_ListIteratorOfListOfShape it; BRep_Builder B; TopAbs_Orientation O1,O2; Standard_Real U1,U2; Standard_Real Tol,Tol1,Tol2; Standard_Boolean OnE1,OnE2; -// for (itLV1.Initialize(LV1),itLV2.Initialize(LV2); -// itLV1.More(); -// itLV1.Next() ,itLV2.Next()) { - - TopoDS_Vertex V = theV; -// TopoDS_Vertex V = TopoDS::Vertex(itLV1.Value()); - - U1 = BRep_Tool::Parameter(V,E1); - U2 = BRep_Tool::Parameter(V,E2); - O1 = V.Orientation(); - O2 = O1;///itLV2.Value().Orientation(); - P1 = BRep_Tool::Pnt(V); - Tol = BRep_Tool::Tolerance( V ); - OnE1 = OnE2 = Standard_False; - + TopoDS_Vertex V = theV; + + U1 = BRep_Tool::Parameter(V,E1); + U2 = BRep_Tool::Parameter(V,E2); + O1 = V.Orientation(); + O2 = O1; + P1 = BRep_Tool::Pnt(V); + Tol = BRep_Tool::Tolerance( V ); + OnE1 = OnE2 = Standard_False; + + //----------------------------------------------------------------- + // Search if the point of intersection is a vertex of E1. + //----------------------------------------------------------------- + for (it.Initialize(VOnE1); it.More(); it.Next()) { + const TopoDS_Vertex& CV = TopoDS::Vertex( it.Value() ); + if (V.IsSame( CV )) { + V1 = V; + OnE1 = Standard_True; + break; + } + P2 = BRep_Tool::Pnt( CV ); + Tol1 = 1.1*(Tol + BRep_Tool::Tolerance( CV )); + if (P1.SquareDistance(P2) <= Tol1*Tol1) { + V = CV; + V1 = V; + OnE1 = Standard_True; + break; + } + } + if (OnE1) { //----------------------------------------------------------------- - // Search if the point of intersection is a vertex of E1. + // Search if the vertex found is still on E2. //----------------------------------------------------------------- - for (it.Initialize(VOnE1); it.More(); it.Next()) { - const TopoDS_Vertex& CV = TopoDS::Vertex( it.Value() ); - if (V.IsSame( CV )) { - V1 = V; - OnE1 = Standard_True; - break; - } - P2 = BRep_Tool::Pnt( CV ); - Tol1 = 1.1*(Tol + BRep_Tool::Tolerance( CV )); - if (P1.SquareDistance(P2) <= Tol1*Tol1) { - V = CV; - V1 = V; - OnE1 = Standard_True; + for (it.Initialize(VOnE2); it.More(); it.Next()) { + if (V.IsSame( it.Value() )) { + OnE2 = Standard_True; + V2 = V; break; } } - if (OnE1) { + } + if (!OnE2) { + for (it.Initialize(VOnE2); it.More(); it.Next()) { //----------------------------------------------------------------- - // Search if the vertex found is still on E2. + // Search if the point of intersection is a vertex of E2. //----------------------------------------------------------------- - for (it.Initialize(VOnE2); it.More(); it.Next()) { - if (V.IsSame( it.Value() )) { - OnE2 = Standard_True; - V2 = V; - break; - } + const TopoDS_Vertex& CV = TopoDS::Vertex( it.Value() ); + P2 = BRep_Tool::Pnt( CV ); + Tol2 = 1.1*(Tol + BRep_Tool::Tolerance( CV )); + if (P1.SquareDistance(P2) <= Tol2*Tol2) { + V = CV; + V2 = V; + OnE2 = Standard_True; + break; } } - if (!OnE2) { - for (it.Initialize(VOnE2); it.More(); it.Next()) { - //----------------------------------------------------------------- - // Search if the point of intersection is a vertex of E2. - //----------------------------------------------------------------- - const TopoDS_Vertex& CV = TopoDS::Vertex( it.Value() ); - P2 = BRep_Tool::Pnt( CV ); - Tol2 = 1.1*(Tol + BRep_Tool::Tolerance( CV )); - if (P1.SquareDistance(P2) <= Tol2*Tol2) { - V = CV; - V2 = V; - OnE2 = Standard_True; - break; - } - } + } + + + if (!OnE1 && !OnE2 && !theF.IsNull()) + { + // analitically find vertices E1 and E2 must pass trough + + TopoDS_Shape F1 = getOtherShape( theF, AsDes->Ascendant( E1 )); + TopoDS_Shape F2 = getOtherShape( theF, AsDes->Ascendant( E2 )); + if (!F1.IsNull() && !F2.IsNull()) + { + OnE1 = findVOnE ( theV, E1, E2, F1, F2, AsDes, V1 ); + OnE2 = findVOnE ( theV, E2, E1, F1, F2, AsDes, V2 ); + if (OnE2) V = V2; + if (OnE1) V = V1; } - if (OnE1 && OnE2) { - if (!V1.IsSame(V2)) { - Standard_Real UV2; - TopoDS_Edge EWE2; - TopoDS_Vertex VI; - const TopTools_ListOfShape& EdgeWithV2 = AsDes->Ascendant(V2); - - for (it.Initialize(EdgeWithV2); it.More(); it.Next()) { - EWE2 = TopoDS::Edge(it.Value()); - VI = V2; - VI.Orientation(TopAbs_INTERNAL); - UV2 = BRep_Tool::Parameter(VI,EWE2); - VI = V1; - VI.Orientation(TopAbs_INTERNAL); - B.UpdateVertex(VI,UV2,EWE2, Max(Tol1,Tol2)); - } - AsDes->Replace(V2,V1); + } + + if (OnE1 && OnE2) { + if (!V1.IsSame(V2)) { + // replace V1 with V2 on all edges V1 is on + Standard_Real UV1; + TopoDS_Edge EWE1; + TopoDS_Vertex VI; + const TopTools_ListOfShape& EdgeWithV1 = AsDes->Ascendant(V1); + + for (it.Initialize(EdgeWithV1); it.More(); it.Next()) { + EWE1 = TopoDS::Edge(it.Value()); + VI = V1; + VI.Orientation(TopAbs_INTERNAL); + UV1 = BRep_Tool::Parameter(VI,EWE1); + VI = V2; + VI.Orientation(TopAbs_INTERNAL); + B.UpdateVertex( VI, UV1, EWE1, GetTolerance( VI, UV1, EWE1, AsDes)); } + AsDes->Replace(V1,V2); + V = V2; } - // add existing vertices instead of new ones - if (!OnE1) { - if (OnE2) { - V.Orientation(TopAbs_INTERNAL); - B.UpdateVertex(V,U1,E1, Tol2); - } - V.Orientation(O1); - NewVOnE1.Prepend(V); + } + + // add existing vertices instead of new ones + if (!OnE1) { + if (OnE2) { + V.Orientation(TopAbs_INTERNAL); + B.UpdateVertex (V, U1, E1, GetTolerance( V, U1, E1, AsDes)); } - if (!OnE2) { - if (OnE1) { - V.Orientation(TopAbs_INTERNAL); - B.UpdateVertex(V,U2,E2, Tol1); - } - V.Orientation(O2); - NewVOnE2.Prepend(V); + V.Orientation(O1); + AsDes->Add(E1,V); + } + if (!OnE2) { + if (OnE1) { + V.Orientation(TopAbs_INTERNAL); + B.UpdateVertex (V, U2, E2, GetTolerance( V, U2, E2, AsDes )); } -// } - - if (!NewVOnE1.IsEmpty()) AsDes->Add(E1,NewVOnE1); - if (!NewVOnE2.IsEmpty()) AsDes->Add(E2,NewVOnE2); + V.Orientation(O2); + AsDes->Add(E2,V); + } return V; } @@ -212,11 +306,11 @@ TopoDS_Vertex Partition_Inter2d::AddVonE(const TopoDS_Vertex& theV, //======================================================================= TopoDS_Vertex Partition_Inter2d::FindEndVertex(const TopTools_ListOfShape& LV, - const Standard_Real f, - const Standard_Real l, - const TopoDS_Edge& E, - Standard_Boolean& isFirst, - Standard_Real& minDU) + const Standard_Real f, + const Standard_Real l, + const TopoDS_Edge& E, + Standard_Boolean& isFirst, + Standard_Real& minDU) { TopoDS_Vertex endV; Standard_Real U, endU, min; @@ -238,7 +332,7 @@ TopoDS_Vertex Partition_Inter2d::FindEndVertex(const TopTools_ListOfShape& LV, isFirst = Standard_True; else isFirst = Standard_False; - + return endV; } @@ -248,10 +342,10 @@ TopoDS_Vertex Partition_Inter2d::FindEndVertex(const TopTools_ListOfShape& LV, //======================================================================= static void treatClosed (const TopoDS_Edge& E1, - const Standard_Real f, - const Standard_Real l, - TopTools_ListOfShape& LV1, - TopTools_ListOfShape& /*LV2*/) + const Standard_Real f, + const Standard_Real l, + TopTools_ListOfShape& LV1, + TopTools_ListOfShape& /*LV2*/) { Standard_Boolean isFirst=0; Standard_Real minDU = 1.e10; @@ -261,12 +355,12 @@ static void treatClosed (const TopoDS_Edge& E1, if (minDU > Precision::PConfusion()) return; // not end point - Standard_Real newU; + Standard_Real newU; if (isFirst) newU = f + (l - f); else newU = l - (l - f); - + // update end parameter BRep_Builder B; endV.Orientation(TopAbs_INTERNAL); @@ -275,21 +369,21 @@ static void treatClosed (const TopoDS_Edge& E1, //======================================================================= //function : EdgesPartition -//purpose : +//purpose : //======================================================================= static void EdgesPartition(const TopoDS_Face& F, - const TopoDS_Edge& E1, - const TopoDS_Edge& E2, - const Handle(BRepAlgo_AsDes)& AsDes, - const TopTools_MapOfShape& NewEdges, - const Standard_Boolean WithOri) + const TopoDS_Edge& E1, + const TopoDS_Edge& E2, + const Handle(BRepAlgo_AsDes)& AsDes, + const TopTools_MapOfShape& NewEdges, + const Standard_Boolean WithOri) { Standard_Real f[3],l[3]; Standard_Real MilTol2; Standard_Real Tol = Max (BRep_Tool::Tolerance(E1), - BRep_Tool::Tolerance(E2)); + BRep_Tool::Tolerance(E2)); MilTol2 = Tol * Tol * 10; BRep_Tool::Range(E1, f[1], l[1]); @@ -319,10 +413,10 @@ static void EdgesPartition(const TopoDS_Face& F, TopExp_Explorer exp(F2, TopAbs_EDGE); TopExp::MapShapes(F1, TopAbs_EDGE, ME); for (; exp.More(); exp.Next()) { - if (ME.Contains( exp.Current())) { - intersect = Standard_False; - break; - } + if (ME.Contains( exp.Current())) { + intersect = Standard_False; + break; + } } } } @@ -341,7 +435,8 @@ static void EdgesPartition(const TopoDS_Face& F, Standard_Boolean rejectreducedsegmentpoints = Standard_False; EInter.InitPoint(rejectreducedsegmentpoints); - for (;EInter.MorePoint();EInter.NextPoint()) { + for ( ; EInter.MorePoint(); EInter.NextPoint() ) + { const TopOpeBRep_Point2d& P2D = EInter.Point(); const gp_Pnt& P = P2D.Value(); TopoDS_Vertex V = BRepLib_MakeVertex(P); @@ -353,36 +448,25 @@ static void EdgesPartition(const TopoDS_Face& F, gp_Pnt P2 = CE2.Value(P2D.Parameter(2)); Standard_Real sqd1 = P1.SquareDistance(P); Standard_Real sqd2 = P2.SquareDistance(P); - if (sqd1 > MilTol2 || sqd2 > MilTol2 ) { - //MESSAGE ( "Inter2d : Solution rejected, dist: " << sqrt(Max(sqd1,sqd2)) ) -#ifdef DEB - if (TestEdges) { - MESSAGE ( " edges : E2d_"< MilTol2 || sqd2 > MilTol2 ) + continue; // add a new vertex to the both edges - Standard_Real toler = 1.5 * Max (Tol, sqrt(Max(sqd1,sqd2)) ); + Standard_Real toler = Max( Tol, sqrt( Max( sqd1, sqd2 ))); Standard_Integer i; for (i = 1; i <= 2; i++) { - Standard_Real U = P2D.Parameter(i); -#ifdef DEB - if (U < f[i]-Tol || U > l[i]+Tol) { - MESSAGE ( "out" ); - } -#endif - V.Orientation(TopAbs_INTERNAL); - B.UpdateVertex( V,U,EI[i], toler); - TopAbs_Orientation OO = TopAbs_REVERSED; - if (WithOri) { - if (P2D.IsVertex(i)) - OO = P2D.Vertex(i).Orientation(); - else if (P2D.Transition(i).Before() == TopAbs_OUT) { - OO = TopAbs_FORWARD; - } - V.Orientation(OO); - if (i == 1) LV1.Append(V); + Standard_Real U = P2D.Parameter(i); + V.Orientation(TopAbs_INTERNAL); + B.UpdateVertex( V,U,EI[i], toler); + TopAbs_Orientation OO = TopAbs_REVERSED; + if (WithOri) { + if (P2D.IsVertex(i)) + OO = P2D.Vertex(i).Orientation(); + else if (P2D.Transition(i).Before() == TopAbs_OUT) { + OO = TopAbs_FORWARD; + } + V.Orientation(OO); + if (i == 1) LV1.Append(V); else LV2.Append(V); } } @@ -410,7 +494,7 @@ static void EdgesPartition(const TopoDS_Face& F, TolConf = Max (Tol, TolConf); TolConf2 = TolConf * TolConf; if (!intersect) - TolConf2 *= 100; + TolConf2 *= 100; Standard_Real SqDist = P1.SquareDistance(P2); if (SqDist <= TolConf2) { @@ -442,27 +526,25 @@ static void EdgesPartition(const TopoDS_Face& F, i = 1; Purge = Standard_False; for (it1LV1.Initialize(LV1),it1LV2.Initialize(LV2); - it1LV1.More(); it1LV1.Next(),it1LV2.Next()) { + it1LV1.More(); + it1LV1.Next(),it1LV2.Next()) { j = 1; it2LV1.Initialize(LV1); while (j < i) { - const TopoDS_Vertex& VE1 = TopoDS::Vertex(it1LV1.Value()); - const TopoDS_Vertex& VE2 = TopoDS::Vertex(it2LV1.Value()); - Standard_Real Tol1 = BRep_Tool::Tolerance( VE1 ); - Standard_Real Tol2 = BRep_Tool::Tolerance( VE2 ); + const TopoDS_Vertex& VE1 = TopoDS::Vertex(it1LV1.Value()); + const TopoDS_Vertex& VE2 = TopoDS::Vertex(it2LV1.Value()); + Standard_Real Tol1 = BRep_Tool::Tolerance( VE1 ); + Standard_Real Tol2 = BRep_Tool::Tolerance( VE2 ); P1 = BRep_Tool::Pnt( VE1 ); P2 = BRep_Tool::Pnt( VE2 ); if (P1.IsEqual(P2, Tol1 + Tol2)) { LV1.Remove(it1LV1); LV2.Remove(it1LV2); - if (AffichPurge) { - MESSAGE ("Vertices confused purged in EdgeInter.") - } - Purge = Standard_True; - break; - } - j++; - it2LV1.Next(); + Purge = Standard_True; + break; + } + j++; + it2LV1.Next(); } if (Purge) break; i++; @@ -471,17 +553,17 @@ static void EdgesPartition(const TopoDS_Face& F, // care of new closed edges, they always intersect with seam at end if (V1[0].IsSame( V1[1] ) && NewEdges.Contains(E1) ) - treatClosed (E1,f[1],l[1],LV1,LV2); + treatClosed (E1, f[1], l[1], LV1, LV2); if (V2[0].IsSame( V2[1] ) && NewEdges.Contains(E2) ) - treatClosed (E2,f[2],l[2],LV2,LV1); - - //--------------------------------- - // Stocking vertex . - //--------------------------------- + treatClosed (E2, f[2], l[2], LV2, LV1); + + //---------------- + // Stocking vertex + //---------------- - //StorePart2d (E1,E2,LV1,LV2,AsDes,Tol); for ( it1LV1.Initialize( LV1 ); it1LV1.More(); it1LV1.Next()) - Partition_Inter2d::AddVonE ( TopoDS::Vertex( it1LV1.Value()), E1,E2,AsDes); + Partition_Inter2d::AddVonE (TopoDS::Vertex( it1LV1.Value()), + E1, E2, AsDes, F); } //======================================================================= @@ -492,8 +574,8 @@ static void EdgesPartition(const TopoDS_Face& F, //======================================================================= void Partition_Inter2d::CompletPart2d (const Handle(BRepAlgo_AsDes)& AsDes, - const TopoDS_Face& F, - const TopTools_MapOfShape& NewEdges) + const TopoDS_Face& F, + const TopTools_MapOfShape& NewEdges) { #ifdef DEB @@ -517,7 +599,7 @@ void Partition_Inter2d::CompletPart2d (const Handle(BRepAlgo_AsDes)& AsDes, const TopTools_ListOfShape& LE = AsDes->Descendant(F); TopoDS_Vertex V1,V2; Standard_Integer j, i = 1; - + TopoDS_Face FF = F; FF.Orientation(TopAbs_FORWARD); @@ -533,8 +615,8 @@ void Partition_Inter2d::CompletPart2d (const Handle(BRepAlgo_AsDes)& AsDes, // between them and with the restrictions edges //---------------------------------------------------------- if ( (!EdgesOfFace.Contains(E1) || !EdgesOfFace.Contains(E2)) && - (NewEdges.Contains(E1) || NewEdges.Contains(E2)) ) { - EdgesPartition(FF,E1,E2,AsDes,NewEdges,Standard_True); + (NewEdges.Contains(E1) || NewEdges.Contains(E2)) ) { + EdgesPartition(FF,E1,E2,AsDes,NewEdges,Standard_True); } it2LE.Next(); j++; @@ -543,3 +625,46 @@ void Partition_Inter2d::CompletPart2d (const Handle(BRepAlgo_AsDes)& AsDes, } } +//======================================================================= +//function : GetTolerance +//purpose : Returns tolerance theV must have atfer its +// addition to theE with theU parameter. theAsDes is +// used to find pcurves of theE +//======================================================================= + +Standard_Real Partition_Inter2d::GetTolerance + (const TopoDS_Vertex & theV, + const Standard_Real theU, + const TopoDS_Edge & theE, + const Handle(BRepAlgo_AsDes)& theAsDes) +{ + Standard_Real aTol = BRep_Tool::Tolerance( theV ); + gp_Pnt aPnt = BRep_Tool::Pnt( theV ); + + // check point on 3D curve + Standard_Real f,l; + Handle(Geom_Curve) C = BRep_Tool::Curve( theE, f, l ); + if (!C.IsNull()) + aTol = Max ( aTol, aPnt.Distance( C->Value( theU ))); + + // check points on pcurves + const TopTools_ListOfShape& aFList = theAsDes->Ascendant( theE ); + TopTools_ListIteratorOfListOfShape aFIt( aFList ); + for ( ; aFIt.More(); aFIt.Next() ) + { + const TopoDS_Face& F = TopoDS::Face( aFIt.Value() ); + Handle(Geom2d_Curve) pcurve = BRep_Tool::CurveOnSurface( theE, F, f, l ); + if (!pcurve.IsNull()) + { + gp_Pnt2d aPnt2d = pcurve->Value( theU ); + TopLoc_Location L; + Handle(Geom_Surface) S = BRep_Tool::Surface( F, L ); + gp_Pnt aPntOnS = S->Value( aPnt2d.X(), aPnt2d.Y() ); + if (!L.IsIdentity()) + aPntOnS.Transform( L.Transformation() ); + aTol = Max ( aTol, aPnt.Distance( aPntOnS )); + } + } + + return aTol; +} diff --git a/src/PARTITION/Partition_Inter2d.hxx b/src/PARTITION/Partition_Inter2d.hxx index 7d82aa34b..059be9613 100644 --- a/src/PARTITION/Partition_Inter2d.hxx +++ b/src/PARTITION/Partition_Inter2d.hxx @@ -71,8 +71,8 @@ public: // Standard_EXPORT static void CompletPart2d(const Handle(BRepAlgo_AsDes)& AsDes,const TopoDS_Face& F,const TopTools_MapOfShape& NewEdges) ; Standard_EXPORT static TopoDS_Vertex FindEndVertex(const TopTools_ListOfShape& VertList,const Standard_Real f,const Standard_Real l,const TopoDS_Edge& E,Standard_Boolean& First,Standard_Real& DU) ; -Standard_EXPORT static TopoDS_Vertex AddVonE(const TopoDS_Vertex& V,const TopoDS_Edge& E1,const TopoDS_Edge& E2,const Handle(BRepAlgo_AsDes)& AsDes) ; - +Standard_EXPORT static TopoDS_Vertex AddVonE(const TopoDS_Vertex& V,const TopoDS_Edge& E1,const TopoDS_Edge& E2,const Handle(BRepAlgo_AsDes)& AsDes,const TopoDS_Face& F) ; +Standard_EXPORT static Standard_Real GetTolerance(const TopoDS_Vertex& theV,const Standard_Real theU,const TopoDS_Edge& theE,const Handle(BRepAlgo_AsDes)& theAsDes) ; diff --git a/src/PARTITION/Partition_Inter3d.cdl b/src/PARTITION/Partition_Inter3d.cdl index 38c504aee..44be26eaf 100644 --- a/src/PARTITION/Partition_Inter3d.cdl +++ b/src/PARTITION/Partition_Inter3d.cdl @@ -68,14 +68,21 @@ is TouchedFaces(me : in out) returns MapOfShape from TopTools ---C++: return & is static; - ---Purpose: return map of - - AsDes(me) returns AsDes from BRepAlgo - is static; + ---Purpose: return map of faces cut by new or section edges NewEdges(me : in out) returns MapOfShape from TopTools ---C++: return & is static; + ---Purpose: return new and section edges + + AsDes(me) returns AsDes from BRepAlgo + is static; + ---Purpose: return an object containing info about + -- Ascendants | Descendants + -- ------------------+--------------------- + -- 1. faces | edges cutting them + -- 2. sectoin edges | new vertices on them + ------------------------------- ---Category: Same domain shapes diff --git a/src/PARTITION/Partition_Inter3d.cxx b/src/PARTITION/Partition_Inter3d.cxx index dc7e4606c..7724b73f1 100644 --- a/src/PARTITION/Partition_Inter3d.cxx +++ b/src/PARTITION/Partition_Inter3d.cxx @@ -27,58 +27,63 @@ // $Header$ using namespace std; -#include "Partition_Inter3d.ixx" #include "Partition_Inter2d.hxx" +#include "Partition_Inter3d.ixx" #include "utilities.h" -#include -#include -#include #include #include #include +#include +#include +#include #include #include +#include +#include +#include +#include #include -#include +#include #include #include -#include -#include -#include -#include -#include +#include #ifdef DEB #include #endif -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include #include -#include +#include +#include #include #include -#include #include -#include +#include +#include +#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include //======================================================================= //function : Partition_Inter3d @@ -191,19 +196,62 @@ static void PutInBounds (const TopoDS_Face& F, if (S->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) { S = (*(Handle_Geom_RectangularTrimmedSurface*)&S)->BasisSurface(); } - //--------------- - // Recadre en U. - //--------------- - if (!S->IsUPeriodic() && !S->IsVPeriodic()) return; + if (!S->IsUPeriodic() && !S->IsVPeriodic()) + return; BRepTools::UVBounds(F,umin,umax,vmin,vmax); + gp_Pnt2d Pf = C2d->Value(f); + gp_Pnt2d Pl = C2d->Value(l); + const Standard_Real Um = 0.34*f + 0.66*l; + gp_Pnt2d Pm = C2d->Value( Um ); + + // sometimes on shpere, pcurve is out of domain by V though S is + // UPeriodic, sometimes it is in domain but nontheless it has + // wrong position. + // Check pcurve position by 3D point + if (S->IsKind(STANDARD_TYPE( Geom_SphericalSurface )) || + S->IsKind(STANDARD_TYPE( Geom_ToroidalSurface ))) + { + // get point on the surface + gp_Pnt Ps = S->Value( Pm.X(), Pm.Y() ); + // get point on the edge + Handle(Geom_Curve) C = BRep_Tool::Curve( E, f, l ); + gp_Pnt Pc = C->Value( Um ); + // compare points + Standard_Real TolE = BRep_Tool::Tolerance( E ); + if ( Pc.SquareDistance( Ps ) * 0.95 < TolE * TolE ) + return; // OK + + // find good UV for Pc: project Pc on S + GeomAdaptor_Surface SA (S); + Extrema_ExtPS anExtPS (Pc, SA, + SA.UResolution( TolE ), SA.VResolution( TolE )); + if (anExtPS.IsDone()) + { + Standard_Integer i, nbExt = anExtPS.NbExt(); + Extrema_POnSurf aPOnSurf; + for (i = 1; i <= nbExt; ++i ) + if (anExtPS.Value( i ) <= TolE) { + aPOnSurf = anExtPS.Point( i ); + break; + } + if (i <= nbExt) { + // a point found + Standard_Real u, v; + aPOnSurf.Parameter( u, v ); + gp_Pnt2d aGoodPm ( u, v ); + C2d->Translate( Pm , aGoodPm ); + } + } + } + + //--------------- + // Recadre en U. + //--------------- if (S->IsUPeriodic()) { Standard_Real period = S->UPeriod(); Standard_Real eps = period*1.e-6; - gp_Pnt2d Pf = C2d->Value(f); - gp_Pnt2d Pl = C2d->Value(l); - gp_Pnt2d Pm = C2d->Value(0.34*f + 0.66*l); Standard_Real minC = Min(Pf.X(),Pl.X()); minC = Min(minC,Pm.X()); Standard_Real maxC = Max(Pf.X(),Pl.X()); maxC = Max(maxC,Pm.X()); Standard_Real du = 0.; @@ -235,9 +283,6 @@ static void PutInBounds (const TopoDS_Face& F, if (S->IsVPeriodic()) { Standard_Real period = S->VPeriod(); Standard_Real eps = period*1.e-6; - gp_Pnt2d Pf = C2d->Value(f); - gp_Pnt2d Pl = C2d->Value(l); - gp_Pnt2d Pm = C2d->Value(0.34*f + 0.66*l); Standard_Real minC = Min(Pf.Y(),Pl.Y()); minC = Min(minC,Pm.Y()); Standard_Real maxC = Max(Pf.Y(),Pl.Y()); maxC = Max(maxC,Pm.Y()); Standard_Real dv = 0.; @@ -309,8 +354,6 @@ void Partition_Inter3d::Inter3D(const TopoDS_Face& F1, while (itLE.More()) { TopoDS_Edge E = TopoDS::Edge(itLE.Value()); -// Standard_Real f,l; -// BRep_Tool::Range(E,f,l); PutInBounds (F1,E,pc1); PutInBounds (F2,E,pc2); @@ -327,48 +370,59 @@ void Partition_Inter3d::Inter3D(const TopoDS_Face& F1, } } - // =================================================== - // Store section edges, same domain faces and verives - // =================================================== + // ======================== + // store same domain faces + // ======================== - TopTools_ListOfShape empty, LSP, LSE; - if ( DatStr->HasSameDomain( F1 )) { // same domain faces + if ( DatStr->HasSameDomain( F1 )) + { + TopTools_ListOfShape emptyList; if (!mySameDomainFM.IsBound(F1)) - mySameDomainFM.Bind(F1,empty); + mySameDomainFM.Bind(F1,emptyList); if (!mySameDomainFM.IsBound(F2)) - mySameDomainFM.Bind(F2,empty); + mySameDomainFM.Bind(F2,emptyList); mySameDomainFM(F1).Append(F2); mySameDomainFM(F2).Append(F1); } + // ==================== + // Store section edges + // ==================== + const TopOpeBRepDS_DataStructure& DS = DatStr->DS(); - Standard_Integer j,i,nes = DS.NbSectionEdges(); - if (!nes) return; + Standard_Integer j,i,nse = DS.NbSectionEdges(); + if (nse == 0) return; TopoDS_Vertex V, sdeV1, sdeV2; TopTools_MapOfShape MV; + TopTools_ListOfShape LSE; // list of section edges + TopoDS_Face dummyF; - // put vertices on section edges - for (i=1;i<=nes;i++) { - - TopoDS_Edge se, sde, oe; // section, same domain, other edge - se = DS.SectionEdge(i); + for (i = 1; i <= nse; i++) + { + const TopoDS_Edge & se = DS.SectionEdge(i); if (! TopB.IsSplit(se,TopAbs_ON)) continue; + LSE.Append( se ); + // add vertices where section edges interferes with other + // edges as its descendant in myAsDes + + TopoDS_Edge sde, oe; // same domain, other edge if (DatStr->HasSameDomain(se)) { sde = TopoDS::Edge( DatStr->SameDomain(se).Value() ); TopExp::Vertices( sde, sdeV1, sdeV2); } - - TColStd_MapOfInteger MIV; + TColStd_MapOfInteger MIV; // indices of added edges TopOpeBRepDS_PointIterator itP (DS.ShapeInterferences( se )); itP.SupportKind( TopOpeBRepDS_EDGE ); + // loop on intersections of se for (; itP.More(); itP.Next()) { oe = TopoDS::Edge( DS.Shape( itP.Support())); if (itP.IsVertex()) { + // there is a vertex at intersection if ( !MIV.Add( itP.Current() )) continue; V = TopoDS::Vertex( DS.Shape( itP.Current())); @@ -376,9 +430,10 @@ void Partition_Inter3d::Inter3D(const TopoDS_Face& F1, oe = sde; V = ReplaceSameDomainV( V , oe ); V.Orientation( TopAbs_INTERNAL); - B.UpdateVertex( V, itP.Parameter(), se, 0.); + B.UpdateVertex( V, itP.Parameter(), se, 0.); // AddVonE() sets real U } else { + // create a new vertex at the intersection point const TopOpeBRepDS_Point& DSP = DS.Point( itP.Current()); V = BRepLib_MakeVertex( DSP.Point() ); V.Orientation( TopAbs_INTERNAL); @@ -393,50 +448,56 @@ void Partition_Inter3d::Inter3D(const TopoDS_Face& F1, } } } - TopoDS_Vertex addedV = Partition_Inter2d::AddVonE( V,se,oe,myAsDes); + // add V on the both intersecting edges + TopoDS_Vertex addedV = Partition_Inter2d::AddVonE( V,se,oe,myAsDes,dummyF); if (!addedV.IsSame( V )) - mySameDomainVM.Bind (V, addedV); - MV.Add( addedV ); + mySameDomainVM.Bind (V, addedV); // equal vertex is already there + + MV.Add( addedV ); // to ease storage of vertices of ON splits } } - TopB.SplitSectionEdges(); + // add section edge to the face it intersects and find + // splits ON that do not have same domain pair + + TopB.SplitSectionEdges(); // let TopB find ON splits - TopTools_DataMapOfShapeShape SEM; // map split - section edge + TopTools_MapOfShape SPM; // map of ON splits TopTools_IndexedMapOfShape ME[2]; TopExp::MapShapes( F1, TopAbs_EDGE, ME[1]); TopExp::MapShapes( F2, TopAbs_EDGE, ME[0]); - // add section edge to the face it intersects and find - // splits ON that do not have same domain pair - - for (i=1;i<=nes;i++) { + TopTools_ListIteratorOfListOfShape itSP, itLSE (LSE); + while ( itLSE.More() ) { - const TopoDS_Edge& se = DS.SectionEdge(i); - if (! TopB.IsSplit(se,TopAbs_ON)) - continue; + TopoDS_Edge se = TopoDS::Edge( itLSE.Value() ); Standard_Integer ancRank = DS.AncestorRank(se); if (ME[ancRank-1].Contains( se )) - continue; // se is an edge of face it intersects + LSE.Remove( itLSE ); // se is an edge of face it intersects + else + itLSE.Next(); const TopoDS_Face& F = (ancRank == 1) ? F2 : F1; // add se to face but dont add twice - TopTools_ListIteratorOfListOfShape itE; + TopTools_ListIteratorOfListOfShape itE( myAsDes->Descendant( F )); if (myAsDes->HasDescendant( F )) { - for (itE.Initialize( (myAsDes->Descendant( F )) ); itE.More(); itE.Next()) + for ( ; itE.More(); itE.Next()) if (se.IsSame( itE.Value() )) break; } - if (!itE.More()) { + if (!itE.More()) + { myAsDes->Add( F, se ); + + // check se pcurve on F Standard_Real tol, f,l, umin=1e100, umax=-1e100; Handle(Geom2d_Curve) pc = BRep_Tool::CurveOnSurface( se, F, f,l); if (pc.IsNull()) { - TopTools_ListIteratorOfListOfShape it( TopB.Splits(se,TopAbs_ON) ); - for ( ;it.More();it.Next()) { - const TopoDS_Edge& E = TopoDS::Edge ( it.Value()); + itSP.Initialize( TopB.Splits(se,TopAbs_ON) ); + for ( ; itSP.More(); itSP.Next()) { + const TopoDS_Edge& E = TopoDS::Edge ( itSP.Value()); BRep_Tool::Range(E, f, l); umin = Min( umin, f); umax = Max( umax, l); @@ -451,45 +512,43 @@ void Partition_Inter3d::Inter3D(const TopoDS_Face& F1, B.UpdateEdge( se, pc, F, tol); } } - + // to detect splits that do not have same domain pair - TopTools_ListIteratorOfListOfShape it( TopB.Splits(se,TopAbs_ON) ); - for ( ;it.More();it.Next()) { - const TopoDS_Edge& S = TopoDS::Edge ( it.Value()); - if (SEM.IsBound( S )) - SEM.UnBind( S ); - else - SEM.Bind( S, se); + // ie which split a face into parts and not pass by its boundary + itSP.Initialize( TopB.Splits(se,TopAbs_ON) ); + for ( ; itSP.More(); itSP.Next()) { + const TopoDS_Shape& SP = itSP.Value(); + if (!SPM.Add( SP )) + SPM.Remove( SP ); } } // store vertices of ON splits and bind section edges to faces - for (i=1;i<=nes;i++) { - - const TopoDS_Edge& se = DS.SectionEdge(i); - if (! TopB.IsSplit(se,TopAbs_ON)) - continue; + + for (itLSE.Initialize (LSE); itLSE.More(); itLSE.Next()) + { + const TopoDS_Shape& se = itLSE.Value(); Standard_Integer ancRank = DS.AncestorRank(se); - if (ME[ancRank-1].Contains( se )) - continue; // se is an edge of face it intersects - TopoDS_Face F = (ancRank == 1) ? F2 : F1; - // add vertices of splits + // add vertices of ON splits which have no same domain pair Standard_Boolean added = Standard_False; - TopTools_ListIteratorOfListOfShape it( TopB.Splits(se,TopAbs_ON) ); - for ( ;it.More();it.Next()) { - const TopoDS_Edge& S = TopoDS::Edge ( it.Value()); - if (!SEM.IsBound( S )) + itSP.Initialize( TopB.Splits(se,TopAbs_ON) ); + for ( ; itSP.More(); itSP.Next()) + { + if (!SPM.Contains( itSP.Value() )) continue; + + const TopoDS_Edge& S = TopoDS::Edge ( itSP.Value()); added = Standard_True; mySectionEdgesAD->Add( F, se ); TopoDS_Vertex VS[2]; TopExp::Vertices (S, VS[0], VS[1]); - for (j=0; j<2; ++j) { + for (j=0; j<2; ++j) + { if (mySameDomainVM.IsBound( VS[j] )) VS[j] = TopoDS::Vertex( mySameDomainVM( VS[j] )); if ( !MV.Contains( VS[j] )) { @@ -498,6 +557,8 @@ void Partition_Inter3d::Inter3D(const TopoDS_Face& F1, TopTools_ListIteratorOfListOfShape itV( myAsDes->Descendant(se) ); for (; itV.More(); itV.Next()) { V = TopoDS::Vertex( itV.Value() ); + if ( V.IsSame( VS[j] )) + break; gp_Pnt P2 = BRep_Tool::Pnt( V ); if (P1.IsEqual( P2, Precision::Confusion())) { mySameDomainVM.Bind (VS[j], V); @@ -508,8 +569,13 @@ void Partition_Inter3d::Inter3D(const TopoDS_Face& F1, if (!itV.More()) // no interferences with edges myAsDes->Add( se, VS[j]); } + + // add ends of ON splits to F in order to detect later + // if a split is on face in IsSplitOn() mySectionEdgesAD->Add( F, VS[j]); } + // in the descendants of F, first go ends of an ON split and + // then a split itself mySectionEdgesAD->Add( F, S ); } if (!added) @@ -544,13 +610,13 @@ void Partition_Inter3d::SetDone(const TopoDS_Face& F1, const TopoDS_Face& F2) { if (!myDone.IsBound(F1)) { - TopTools_ListOfShape empty; - myDone.Bind(F1,empty); + TopTools_ListOfShape emptyList; + myDone.Bind(F1,emptyList); } myDone(F1).Append(F2); if (!myDone.IsBound(F2)) { - TopTools_ListOfShape empty; - myDone.Bind(F2,empty); + TopTools_ListOfShape emptyList; + myDone.Bind(F2,emptyList); } myDone(F2).Append(F1); } @@ -583,7 +649,6 @@ void Partition_Inter3d::StorePart3d(const TopoDS_Face& F1, const TopoDS_Face& F2, const TopTools_ListOfShape& LInt) { - if (!LInt.IsEmpty()) { myAsDes->Add( F1,LInt); myAsDes->Add( F2,LInt); @@ -673,8 +738,8 @@ const TopTools_ListOfShape& Partition_Inter3d::SameDomain(const TopoDS_Face& F) if (mySameDomainFM.IsBound( F )) return mySameDomainFM (F); - static TopTools_ListOfShape empty; - return empty; + static TopTools_ListOfShape emptyList; + return emptyList; } //======================================================================= diff --git a/src/PARTITION/Partition_Loop2d.cxx b/src/PARTITION/Partition_Loop2d.cxx index 1e0a25787..9b229f979 100644 --- a/src/PARTITION/Partition_Loop2d.cxx +++ b/src/PARTITION/Partition_Loop2d.cxx @@ -1,6 +1,6 @@ // GEOM PARTITION : partition algorithm // -// Copyright (C) 2003 CEA/DEN, EDF R&D +// Copyright (C) 2003 CEA/DEN, EDF R& D // // // @@ -18,6 +18,7 @@ using namespace std; #include #include #include +#include #include #include #include @@ -115,18 +116,72 @@ void Partition_Loop2d::AddSectionEdge (const TopoDS_Edge& E) } } +//======================================================================= +//function : preciseU +//purpose : find u such that the 3D point on theE is just out of tolerance +// of theV +//======================================================================= + +static Standard_Real preciseU (const BRepAdaptor_Surface& theSurf, + const TopoDS_Edge& theE, + const TopoDS_Vertex& theV, + const Handle(Geom2d_Curve)& theC, + const Standard_Boolean theFirstEnd) +{ + Standard_Boolean isForward = ( theE.Orientation () == TopAbs_FORWARD ); + if (theFirstEnd) isForward = !isForward; + + // find the first point in 2d and 3d + Standard_Real f,l; + BRep_Tool::Range( theE, f, l ); + Standard_Real u0 = isForward ? l : f; + gp_Pnt2d aP2d0 = theC->Value( u0 ); + gp_Pnt aPnt0 = theSurf.Value( aP2d0.X(), aP2d0.Y() ); + + // shift in 2d and 3d + Standard_Real du = ( l - f ) / 100, du3d = 0; + if (isForward) + du = -du; + + // target parameter + Standard_Real u; + + while (du3d < ::RealSmall()) + { + // u for test + u = u0 + du; + du *= 10; // for the next iteration: increase du untill du3d is large enough + + // find out how u is far from u0 in 3D + gp_Pnt2d aP2d = theC->Value( u ); + gp_Pnt aPnt = theSurf.Value( aP2d.X(), aP2d.Y() ); + du3d = aPnt0.Distance( aPnt ); + } + + // find u such that the 3D point is just out of tolerance of theV + Standard_Real tolV = BRep_Tool::Tolerance( theV ) + Precision::Confusion(); + u = u0 + du * tolV / du3d; + + // check that u is within the range + if ( isForward ? (u < f) : (u > l) ) + u = u0 + du; + + return u; +} + //======================================================================= //function : SelectEdge -//purpose : Find the edge connected by the vertex in the list . -// Is erased of the list. If is too in the list -// with the same orientation, it's erased of the list +//purpose : Find in the list the edge connected with by +// the vertex . +// is removed from the list. If is in +// with the same orientation, it's removed from the list //======================================================================= static Standard_Boolean SelectEdge(const BRepAdaptor_Surface& Surf, - const TopoDS_Edge& CE, - const TopoDS_Vertex& CV, - TopoDS_Edge& NE, - const TopTools_ListOfShape& LE) + const TopoDS_Edge& CE, + const TopoDS_Vertex& CV, + TopoDS_Edge& NE, + const TopTools_ListOfShape& LE) { NE.Nullify(); @@ -136,68 +191,90 @@ static Standard_Boolean SelectEdge(const BRepAdaptor_Surface& Surf, // - Test the edges differents of CE //-------------------------------------------------------------- TopoDS_Face FForward = Surf.Face(); + TopoDS_Edge aPrevNE; - Standard_Real cf, cl, f, l; - Handle(Geom2d_Curve) Cc, C; - Cc = BRep_Tool::CurveOnSurface(CE,FForward,cf,cl); - -// Standard_Real tolV, tol2d2; - Standard_Real tolV = BRep_Tool::Tolerance(CV); -// tol2d2 = Max ( Surf.UResolution(tolV) , Surf.VResolution(tolV) ); -// tol2d2 = 2 * Max ( tol2d2, Precision::PConfusion() ); -// tol2d2 *= tol2d2; - - Standard_Real uc,u, du = Precision::PConfusion(); - if (CE.Orientation () == TopAbs_FORWARD) uc = cl + du; - else uc = cf - du; - - gp_Vec2d CTg1, Tg1; + gp_Vec2d CTg1, Tg1, CTg2, Tg2; gp_Pnt2d PC, P; - gp_Pnt P3d; + Standard_Real f, l; + Handle(Geom2d_Curve) Cc, C; + Cc = BRep_Tool::CurveOnSurface(CE,FForward,f,l); + + Standard_Boolean isForward = ( CE.Orientation () == TopAbs_FORWARD ); + Standard_Real uc, u, du = Precision::PConfusion(); + uc = isForward ? ( l - du ) : ( f + du ); Cc->D1(uc, PC, CTg1); - if (CE.Orientation () == TopAbs_REVERSED) CTg1.Reverse(); + if (!isForward) CTg1.Reverse(); - Standard_Real anglemin = 3 * PI; -// Standard_Real sqdist, sqdistmin = 1.0e50; + Standard_Real anglemin = 3 * PI, tolAng = 1.e-8; + // select an edge whose first derivative is most left of CTg1 + // ie an angle between Tg1 and CTg1 is least TopTools_ListIteratorOfListOfShape itl; for ( itl.Initialize(LE); itl.More(); itl.Next()) { const TopoDS_Edge& E = TopoDS::Edge(itl.Value()); if (E.IsSame(CE)) - continue; + continue; if (! CV.IsSame( TopExp::FirstVertex( E, Standard_True ))) - continue; + continue; - C = BRep_Tool::CurveOnSurface(E,FForward,f,l); - if (E.Orientation () == TopAbs_FORWARD) u = f + du; - else u = l - du; + isForward = ( E.Orientation () == TopAbs_FORWARD ); + // get E curve + C = BRep_Tool::CurveOnSurface(E,FForward,f,l); + // get the first derivative Tg1 + u = isForward ? ( f + du ) : ( l - du ); C->D1(u, P, Tg1); -// if (P.SquareDistance(PC); > tol2d2) -// continue; - - if (E.Orientation () == TopAbs_REVERSED) Tg1.Reverse(); + if (!isForward) Tg1.Reverse(); + // -PI < angle < PI Standard_Real angle = Tg1.Angle(CTg1); + if (PI - Abs(angle) <= tolAng) + { + // an angle is too close to PI; assure that an angle sign really + // reflects an edge position: +PI - an edge is worst, + // -PI - an edge is best. + u = preciseU( Surf, CE, CV, Cc, Standard_False); + gp_Vec2d CTg; + Cc->D1(u, PC, CTg); + if (CE.Orientation() == TopAbs_REVERSED) CTg.Reverse(); + + u = preciseU( Surf, E, CV, C, Standard_True); + C->D1(u, P, Tg1); + if (!isForward) Tg1.Reverse(); + + angle = Tg1.Angle(CTg); + } + + Standard_Boolean isClose = ( Abs( angle - anglemin ) <= tolAng ); if (angle <= anglemin) { - anglemin = angle ; - NE = E; -#ifdef DEB -// sqdist = P.SquareDistance(PC); -// if (sqdist < sqdistmin) -// sqdistmin = sqdist; - P3d = Surf.Value (PC.X(), PC.Y()); -#endif + if (isClose) + aPrevNE = NE; + else + aPrevNE.Nullify(); + anglemin = angle ; + NE = E; } + else + if (isClose) + aPrevNE = E; + } -#ifdef DEB - if (!NE.IsNull() && P3d.Distance( BRep_Tool::Pnt(CV)) > tolV) { - MESSAGE( "DISTANCE MORE THAN VERTEX TOL (" << tolV << ")" ); - cout << "point p " << P3d.X() << " " << P3d.Y() << " " << P3d.Z() << endl; + if (!aPrevNE.IsNull()) { + // select one of close edges, the most left one. + Cc = BRep_Tool::CurveOnSurface( NE, FForward, f, l ); + uc = preciseU( Surf, NE, CV, Cc, Standard_True); + Cc->D1(uc, PC, CTg1); + if (NE.Orientation() != TopAbs_FORWARD) CTg1.Reverse(); + + u = preciseU( Surf, aPrevNE, CV, C, Standard_True); + C->D1(u, P, Tg1); + if (aPrevNE.Orientation() != TopAbs_FORWARD) Tg1.Reverse(); + + if ( Tg1.Angle(CTg1) < 0) + NE = aPrevNE; } -#endif } else if (LE.Extent() == 1) { NE = TopoDS::Edge(LE.First()); @@ -214,10 +291,10 @@ static Standard_Boolean SelectEdge(const BRepAdaptor_Surface& Surf, //======================================================================= static Standard_Boolean SamePnt2d(const TopoDS_Vertex& V1, - const TopoDS_Edge& E1, - const TopoDS_Vertex& V2, - const TopoDS_Edge& E2, - const TopoDS_Face& F) + const TopoDS_Edge& E1, + const TopoDS_Vertex& V2, + const TopoDS_Edge& E2, + const TopoDS_Face& F) { Standard_Real f1,f2,l1,l2; Handle(Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(E1,F,f1,l1); @@ -238,8 +315,8 @@ static Standard_Boolean SamePnt2d(const TopoDS_Vertex& V1, //======================================================================= static void StoreInMVE (const TopoDS_Face& /*F*/, - TopoDS_Edge& E, - TopTools_DataMapOfShapeListOfShape& MVE ) + TopoDS_Edge& E, + TopTools_DataMapOfShapeListOfShape& MVE ) { TopoDS_Vertex V1, V2; @@ -259,11 +336,11 @@ static void StoreInMVE (const TopoDS_Face& /*F*/, //======================================================================= //function : RemoveFromMVE -//purpose : +//purpose : //======================================================================= static void RemoveFromMVE(const TopoDS_Edge& E, - TopTools_DataMapOfShapeListOfShape& MVE) + TopTools_DataMapOfShapeListOfShape& MVE) { TopTools_ListIteratorOfListOfShape itl; TopoDS_Vertex V1,V2; @@ -271,15 +348,15 @@ static void RemoveFromMVE(const TopoDS_Edge& E, if (MVE.IsBound(V1)) for ( itl.Initialize(MVE(V1)); itl.More(); itl.Next()) { if (itl.Value().IsEqual(E)) { - MVE(V1).Remove(itl); - break; + MVE(V1).Remove(itl); + break; } } if (MVE.IsBound(V2)) for ( itl.Initialize(MVE(V2)); itl.More(); itl.Next()) { if (itl.Value().IsEqual(E)) { - MVE(V2).Remove(itl); - break; + MVE(V2).Remove(itl); + break; } } } @@ -289,21 +366,21 @@ static void RemoveFromMVE(const TopoDS_Edge& E, //======================================================================= static void addConnected(const TopoDS_Shape& E, - TopTools_MapOfShape& EM, - TopTools_MapOfShape& VM, - const TopTools_DataMapOfShapeListOfShape& MVE) + TopTools_MapOfShape& EM, + TopTools_MapOfShape& VM, + const TopTools_DataMapOfShapeListOfShape& MVE) { // Loop on vertices of E TopoDS_Iterator itV ( E ); for ( ; itV.More(); itV.Next()) { if ( ! VM.Add ( itV.Value() )) continue; - + // Loop on edges sharing V TopTools_ListIteratorOfListOfShape itE( MVE( itV.Value() ) ); for (; itE.More(); itE.Next()) { if ( EM.Add( itE.Value() )) - addConnected ( itE.Value(), EM, VM, MVE ); + addConnected ( itE.Value(), EM, VM, MVE ); } } } @@ -312,31 +389,31 @@ static void addConnected(const TopoDS_Shape& E, //purpose : //======================================================================= -static Standard_Boolean canPassToOld (const TopoDS_Shape& V, - TopTools_MapOfShape& UsedShapesMap, - const TopTools_DataMapOfShapeListOfShape& MVE, - const TopTools_MapOfShape& SectionEdgesMap) -{ - TopTools_ListIteratorOfListOfShape itE( MVE(V) ); - // Loop on edges sharing V - for (; itE.More(); itE.Next()) { - if ( !UsedShapesMap.Add( itE.Value() )) - continue; // already checked - - if ( !SectionEdgesMap.Contains( itE.Value() )) - return Standard_True; // WE PASSED - - TopoDS_Iterator itV( itE.Value() ); - // Loop on vertices of an edge - for (; itV.More(); itV.Next()) { - if ( !UsedShapesMap.Add( itV.Value() )) - continue; // already checked - else - return canPassToOld( itV.Value(), UsedShapesMap, MVE, SectionEdgesMap); - } - } - return Standard_False; -} +// static Standard_Boolean canPassToOld (const TopoDS_Shape& V, +// TopTools_MapOfShape& UsedShapesMap, +// const TopTools_DataMapOfShapeListOfShape& MVE, +// const TopTools_MapOfShape& SectionEdgesMap) +// { +// TopTools_ListIteratorOfListOfShape itE( MVE(V) ); +// // Loop on edges sharing V +// for (; itE.More(); itE.Next()) { +// if ( !UsedShapesMap.Add( itE.Value() )) +// continue; // already checked + +// if ( !SectionEdgesMap.Contains( itE.Value() )) +// return Standard_True; // WE PASSED + +// TopoDS_Iterator itV( itE.Value() ); +// // Loop on vertices of an edge +// for (; itV.More(); itV.Next()) { +// if ( !UsedShapesMap.Add( itV.Value() )) +// continue; // already checked +// else +// return canPassToOld( itV.Value(), UsedShapesMap, MVE, SectionEdgesMap); +// } +// } +// return Standard_False; +// } //======================================================================= //function : MakeDegenAndSelect @@ -346,11 +423,11 @@ static Standard_Boolean canPassToOld (const TopoDS_Shape& V, //======================================================================= static TopoDS_Edge MakeDegenAndSelect(const TopoDS_Edge& CE, - const TopoDS_Vertex& CV, - TopoDS_Edge& NE, - TopTools_SequenceOfShape& EdgesSeq, - TColStd_SequenceOfReal& USeq, - const TopoDS_Edge& DE) + const TopoDS_Vertex& CV, + TopoDS_Edge& NE, + TopTools_SequenceOfShape& EdgesSeq, + TColStd_SequenceOfReal& USeq, + const TopoDS_Edge& DE) { if (EdgesSeq.Length() < 3) { if (CE == EdgesSeq.First()) @@ -378,7 +455,7 @@ static TopoDS_Edge MakeDegenAndSelect(const TopoDS_Edge& CE, for (i=1; i<= nb; ++i) { dU = USeq(i) - U1; if (isReversed ? (dU > 0) : (dU < 0)) - continue; + continue; dU = Abs( dU ); if ( dU > dUmin || IsEqual( dU, 0.)) continue; @@ -417,12 +494,12 @@ static TopoDS_Edge MakeDegenAndSelect(const TopoDS_Edge& CE, //======================================================================= static void prepareDegen (const TopoDS_Edge& DegEdge, - const TopoDS_Face& F, - const TopTools_DataMapOfShapeListOfShape& MVE, - TopTools_SequenceOfShape& EdgesSeq, - TColStd_SequenceOfReal& USeq, - TopTools_DataMapOfShapeInteger& MVDEI, - const Standard_Integer DegEdgeIndex) + const TopoDS_Face& F, + const TopTools_DataMapOfShapeListOfShape& MVE, + TopTools_SequenceOfShape& EdgesSeq, + TColStd_SequenceOfReal& USeq, + TopTools_DataMapOfShapeInteger& MVDEI, + const Standard_Integer DegEdgeIndex) { const TopoDS_Vertex& V = TopExp::FirstVertex ( DegEdge ); MVDEI.Bind ( V, DegEdgeIndex ); @@ -456,9 +533,9 @@ static void prepareDegen (const TopoDS_Edge& DegEdge, // seam edge: select U among f and l Standard_Boolean first = Standard_True; if ( V.IsSame ( TopExp::FirstVertex( E, Standard_True ) )) - first = Standard_False; + first = Standard_False; if ( DegEdge.Orientation() == TopAbs_REVERSED ) - first = !first; + first = !first; U = first ? f : l; } else if ( EUMap.IsBound( E ) ) { @@ -470,8 +547,8 @@ static void prepareDegen (const TopoDS_Edge& DegEdge, C.Initialize( E, F ); InterCC.Perform ( DC, C , Tol, Tol ); if (! InterCC.IsDone() || InterCC.NbPoints() == 0) { - MESSAGE ( "NO 2d INTERSECTION ON DEGENERATED EDGE" ); - continue; + MESSAGE ( "NO 2d INTERSECTION ON DEGENERATED EDGE" ); + continue; } // hope there is only one point of intersection U = InterCC.Point( 1 ).ParamOnFirst(); @@ -566,13 +643,13 @@ void Partition_Loop2d::Perform() // only a seam is allowed twice in a wire, the others should be removed if (addedEM.Add ( CE ) || BRep_Tool::IsClosed( CE, myFace ) ) - WEL.Append( CE ); + WEL.Append( CE ); else { - doubleEM.Add( CE ); - RemoveFromMVE (CE,MVE2); - TopoDS_Edge CERev = CE; - CERev.Reverse(); - RemoveFromMVE (CERev,MVE2); + doubleEM.Add( CE ); + RemoveFromMVE (CE,MVE2); + TopoDS_Edge CERev = CE; + CERev.Reverse(); + RemoveFromMVE (CERev,MVE2); } RemoveFromMVE (CE,MVE); @@ -580,161 +657,158 @@ void Partition_Loop2d::Perform() CV = TopExp::LastVertex( CE, Standard_True); if (isInternCW && !mySectionEdges.Contains(CE)) - // wire is internal if all edges are section ones - isInternCW = Standard_False; + // wire is internal if all edges are section ones + isInternCW = Standard_False; if (MVDEI.IsBound( CV )) { // CE comes to the degeneration - iDeg = MVDEI( CV ); - TopoDS_Edge NewDegen; - NewDegen = MakeDegenAndSelect( CE, CV, NE, SEID[iDeg], SeqU[iDeg], DE[iDeg]); - WEL.Append( NewDegen ); + iDeg = MVDEI( CV ); + TopoDS_Edge NewDegen; + NewDegen = MakeDegenAndSelect( CE, CV, NE, SEID[iDeg], SeqU[iDeg], DE[iDeg]); + WEL.Append( NewDegen ); CE = NE; End = CV.IsSame( VF ); - continue; + continue; } //-------------- // stop test //-------------- if (MVE(CV).IsEmpty()) { - End=Standard_True; - MVE.UnBind(CV); + End=Standard_True; + MVE.UnBind(CV); } else if (CV.IsSame(VF) && SamePnt2d(CV,CE, VF,EF, myFace) ) { - End = Standard_True; + End = Standard_True; } else { - //---------------------------- - // select new current edge - //---------------------------- - if (! SelectEdge (Surface,CE,CV,NE,MVE(CV))) { - MESSAGE ( " NOT CLOSED WIRE " ); - End=Standard_True; - } - else - CE = NE; + //---------------------------- + // select new current edge + //---------------------------- + if (! SelectEdge (Surface,CE,CV,NE,MVE(CV))) { + MESSAGE ( " NOT CLOSED WIRE " ); + End=Standard_True; + } + else + CE = NE; } - } // while ( !End ) + } // while ( !End ) + - // WEL is built, built wire(s) - + itl.Initialize( WEL ); if ( doubleEM.IsEmpty()) { // no double edges B.MakeWire( NW ); for (; itl.More(); itl.Next()) - B.Add ( NW, itl.Value()); + B.Add ( NW, itl.Value()); if (isInternCW) myInternalWL.Append(NW); else myNewWires.Append (NW); } - + else { // remove double and degenerated edges from WEL while (itl.More()) { - const TopoDS_Edge& E = TopoDS::Edge ( itl.Value() ); - if ( doubleEM.Contains( E ) || BRep_Tool::Degenerated( E )) - WEL.Remove( itl ); - else - itl.Next(); + const TopoDS_Edge& E = TopoDS::Edge ( itl.Value() ); + if ( doubleEM.Contains( E ) || BRep_Tool::Degenerated( E )) + WEL.Remove( itl ); + else + itl.Next(); } if ( WEL.IsEmpty()) - continue; + continue; // remove double edges from SEID and SeqU Standard_Integer i,j; for (j=0; j<2; ++j) { - for (i=1; i<=SEID[j].Length(); ++i) { - if (doubleEM.Contains( SEID[j].Value(i))) { - SEID[j].Remove( i ); - SeqU[j].Remove( i-- ); - } - } + for (i=1; i<=SEID[j].Length(); ++i) { + if (doubleEM.Contains( SEID[j].Value(i))) { + SEID[j].Remove( i ); + SeqU[j].Remove( i-- ); + } + } } // removal of doulbe edges can explode a wire into parts, // make new wires of them. // A Loop like previous one but without 2d check while ( !WEL.IsEmpty() ) { - CE = TopoDS::Edge( WEL.First() ); - WEL.RemoveFirst(); - B.MakeWire( NW ); - VF = TopExp::FirstVertex ( EF, Standard_True); - - End = Standard_False; - while ( !End) { - B.Add( NW, CE ); - CV = TopExp::LastVertex ( CE, Standard_True); - - if (MVDEI.IsBound( CV )) { // CE comes to the degeneration - iDeg = MVDEI( CV ); + CE = TopoDS::Edge( WEL.First() ); + WEL.RemoveFirst(); + B.MakeWire( NW ); + VF = TopExp::FirstVertex ( CE, Standard_True); + + End = Standard_False; + while ( !End) { + B.Add( NW, CE ); + CV = TopExp::LastVertex ( CE, Standard_True); + + if (MVDEI.IsBound( CV )) { // CE comes to the degeneration + iDeg = MVDEI( CV ); TopoDS_Edge NewDegen; NewDegen = MakeDegenAndSelect( CE, CV, NE, SEID[iDeg], SeqU[iDeg], DE[iDeg]); B.Add( NW, NewDegen ); End = CV.IsSame( VF ); - CE = NE; - if (!NE.IsNull()) { // remove NE from WEL - for (itl.Initialize( WEL ); itl.More(); itl.Next()) - if ( NE == itl.Value()) { - WEL.Remove( itl ); - break; - } - } - } // end degeneration - - else { - if (CV.IsSame( VF )) { - End = Standard_True; - continue; - } - // edges in WEL most often are well ordered - // so try to iterate until the End - Standard_Boolean add = Standard_False; - itl.Initialize(WEL); - while ( itl.More() && !End) { + CE = NE; + if (!NE.IsNull()) { // remove NE from WEL + for (itl.Initialize( WEL ); itl.More(); itl.Next()) + if ( NE == itl.Value()) { + WEL.Remove( itl ); + break; + } + } + } // end degeneration + + else { + if (CV.IsSame( VF )) { + End = Standard_True; + continue; + } + // edges in WEL most often are well ordered + // so try to iterate until the End + Standard_Boolean add = Standard_False; + itl.Initialize(WEL); + while ( itl.More() && !End) { NE = TopoDS::Edge( itl.Value() ); if ( CV.IsSame( TopExp::FirstVertex( NE, Standard_True ))) { WEL.Remove( itl ); - if (add) - B.Add( NW, CE ); - CE = NE; + if (add) + B.Add( NW, CE ); + CE = NE; add = Standard_True; CV = TopExp::LastVertex( CE, Standard_True); if (MVDEI.IsBound( CV ) || CV.IsSame( VF )) break; } - else - itl.Next(); - } - if (!add) - End = Standard_True; - } - } // !End - - myInternalWL.Append( NW ); + else + itl.Next(); + } + if (!add) + End = Standard_True; + } + } // !End + + myInternalWL.Append( NW ); } } // end building new wire(s) from WEL } // end Loop on MVE - + // all wires are built - - + + // ============================================================ // select really internal wires i.e. those from which we can`t // pass to an old (not section) edge // ============================================================ Standard_Integer nbIW = myInternalWL.Extent(); - if ( nbIW == 1 ) { - TopTools_MapOfShape UsedShapes( 2*NbConstEdges ); - TopExp_Explorer expV (myInternalWL.First(), TopAbs_VERTEX); - if (canPassToOld (expV.Current(), UsedShapes, MVE2, mySectionEdges)) - myNewWires.Append ( myInternalWL ); - } - else if ( nbIW > 1 ) { + if (nbIW == 0) + return; + + if ( myNewWires.Extent() != 1 && nbIW > 1) { TopTools_MapOfShape outerEM (NbConstEdges); // edges connected to non-section ones TopTools_MapOfShape visitedVM (NbConstEdges); for ( itl.Initialize( myConstEdges ); itl.More(); itl.Next()) { - if ( ! mySectionEdges.Contains( itl.Value() )) + if ( ! mySectionEdges.Contains( itl.Value() )) addConnected (itl.Value(), outerEM, visitedVM, MVE2); } // if an edge of a wire is in , the wire is not internal @@ -757,13 +831,13 @@ void Partition_Loop2d::Perform() //======================================================================= static Standard_Boolean isHole (const TopoDS_Wire& W, - const TopoDS_Face& F) + const TopoDS_Face& F) { BRep_Builder B; TopoDS_Shape newFace = F.EmptyCopied(); B.Add(newFace,W.Oriented(TopAbs_FORWARD)); BRepTopAdaptor_FClass2d classif (TopoDS::Face(newFace), - Precision::PConfusion()); + Precision::PConfusion()); return (classif.PerformInfinitePoint() == TopAbs_IN); } @@ -773,8 +847,8 @@ static Standard_Boolean isHole (const TopoDS_Wire& W, //======================================================================= static Standard_Boolean isInside(const TopoDS_Face& F, - const TopoDS_Wire& W1, - const TopoDS_Wire& W2) + const TopoDS_Wire& W1, + const TopoDS_Wire& W2) { // make a face with wire W2 BRep_Builder B; @@ -784,10 +858,12 @@ static Standard_Boolean isInside(const TopoDS_Face& F, // get any 2d point of W1 TopExp_Explorer exp(W1,TopAbs_EDGE); - const TopoDS_Edge& edg = TopoDS::Edge(exp.Current()); + if (BRep_Tool::Degenerated( TopoDS::Edge( exp.Current() ))) + exp.Next(); + const TopoDS_Edge& e = TopoDS::Edge(exp.Current()); Standard_Real f,l; - Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(edg,F,f,l); - gp_Pnt2d pt2d(C2d->Value(f)); + Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(e,F,f,l); + gp_Pnt2d pt2d(C2d->Value( 0.5 * ( f + l ))); BRepTopAdaptor_FClass2d classif(newFace,Precision::PConfusion()); return (classif.Perform(pt2d) == TopAbs_IN); @@ -822,8 +898,8 @@ const TopTools_ListOfShape& Partition_Loop2d::NewFaces() const //======================================================================= static void findEqual (TopTools_ListOfShape& WL, - TopTools_DataMapOfShapeShape& EqWM, - const TopoDS_Face& F) + TopTools_DataMapOfShapeShape& EqWM, + const TopoDS_Face& F) { TopTools_ListIteratorOfListOfShape it1, it2; Standard_Integer i,j; @@ -832,7 +908,7 @@ static void findEqual (TopTools_ListOfShape& WL, if (IndMap.Contains(i)) continue; const TopoDS_Wire& Wire1 = TopoDS::Wire( it1.Value()); - + for (it2.Initialize(WL), j=1; it2.More(); it2.Next(), j++) { if (j <= i || IndMap.Contains(j)) continue; @@ -843,19 +919,19 @@ static void findEqual (TopTools_ListOfShape& WL, const TopoDS_Shape& Wire2 = it2.Value(); TopoDS_Iterator itE ( Wire2); for (; itE.More(); itE.Next()) { - if ( !EdgesMap.Contains( itE.Value()) ) - break; + if ( !EdgesMap.Contains( itE.Value()) ) + break; } if (!itE.More()) { // all edges are same - if (isHole( Wire1, F)) { - EqWM.Bind ( Wire1, Wire2 ); - } - else { - EqWM.Bind ( Wire2, Wire1 ); - } - IndMap.Add(i); - IndMap.Add(j); - break; + if (isHole( Wire1, F)) { + EqWM.Bind ( Wire1, Wire2 ); + } + else { + EqWM.Bind ( Wire2, Wire1 ); + } + IndMap.Add(i); + IndMap.Add(j); + break; } } } @@ -877,20 +953,26 @@ static void findEqual (TopTools_ListOfShape& WL, //======================================================================= static void classify(const TopTools_DataMapOfShapeShape& EqWM, - BRepAlgo_AsDes& OuterInner, - const TopoDS_Face& F) + BRepAlgo_AsDes& OuterInner, + const TopoDS_Face& F) { TopTools_DataMapIteratorOfDataMapOfShapeShape it1, it2; for (it1.Initialize(EqWM); it1.More(); it1.Next()) { - for (it2.Initialize(EqWM); it2.More(); it2.Next()) { - if (it1.Value().IsSame( it2.Value() )) continue; + // find next after it1.Value() + for (it2.Initialize(EqWM); it2.More(); it2.Next()) + if (it1.Value().IsSame( it2.Value() )) + { + it2.Next(); + break; + } + for ( ; it2.More(); it2.Next()) { const TopoDS_Wire& Wire1 = TopoDS::Wire( it1.Value() ); const TopoDS_Wire& Wire2 = TopoDS::Wire( it2.Value() ); if (isInside(F, Wire1, Wire2)) - OuterInner.Add (Wire2, Wire1); + OuterInner.Add (Wire2, Wire1); else if (isInside(F, Wire2, Wire1)) - OuterInner.Add (Wire1, Wire2); + OuterInner.Add (Wire1, Wire2); } } } @@ -902,28 +984,12 @@ static void classify(const TopTools_DataMapOfShapeShape& EqWM, // intersections //======================================================================= -//#define USE_BREPFEAT_SPLITSHAPE - -#ifdef USE_BREPFEAT_SPLITSHAPE - -# include -void Partition_Loop2d::WiresToFaces(const BRepAlgo_Image& EdgeImage) -#else - -# include void Partition_Loop2d::WiresToFaces(const BRepAlgo_Image& ) -#endif { Standard_Integer nbW = myNewWires.Extent() + myInternalWL.Extent(); if (nbW==0) return; -#ifndef USE_BREPFEAT_SPLITSHAPE - - // ============================================================ - // use BRepAlgo_FaceRestrictor to make faces - // ============================================================ - BRepAlgo_FaceRestrictor FR; FR.Init (myFace,Standard_False); @@ -932,7 +998,7 @@ void Partition_Loop2d::WiresToFaces(const BRepAlgo_Image& ) // sometimes 1-2 faces are missing ). // So we use it as less as possible: no holes -> make faces by hands - + // are there holes in myFace ? Standard_Boolean hasOldHoles = Standard_False; TopoDS_Iterator itOldW (myFace); @@ -953,7 +1019,7 @@ void Partition_Loop2d::WiresToFaces(const BRepAlgo_Image& ) } return; } - + // FaceRestrictor can't classify wires build on all the same edges // and gives incorrect result in such cases (ex. a plane cut into 2 parts by cylinder) // We must make faces of equal wires separately. One of equal wires makes a @@ -968,7 +1034,7 @@ void Partition_Loop2d::WiresToFaces(const BRepAlgo_Image& ) if (hasOldHoles) myInternalWL.Append( myNewWires ); // an old wire can be inside an equal wire - + // classify equal wire pairs BRepAlgo_AsDes OuterInner; classify (EqWM,OuterInner,myFace); @@ -980,69 +1046,79 @@ void Partition_Loop2d::WiresToFaces(const BRepAlgo_Image& ) // find most internal wires among pairs (key - hole, value - outer part) TopTools_DataMapIteratorOfDataMapOfShapeShape it(EqWM); + Standard_Integer nbEqW = EqWM.Extent(); // protection against infinite loop for ( ; it.More(); it.Next()) { - TopoDS_Wire outerW = TopoDS::Wire ( it.Value() ); - if ( OuterInner.HasDescendant( outerW ) && // has internal - ! OuterInner.Descendant( outerW ).IsEmpty() ) - continue; + TopoDS_Wire outerW = TopoDS::Wire ( it.Value() ); + if ( OuterInner.HasDescendant( outerW ) && // has internal + ! OuterInner.Descendant( outerW ).IsEmpty() ) + continue; - FR.Add( outerW ); + FR.Add( outerW ); // add internal wires that are inside of outerW TopTools_ListIteratorOfListOfShape itIW (myInternalWL); while ( itIW.More()) { TopoDS_Wire IW = TopoDS::Wire ( itIW.Value() ); if ( isInside (myFace, IW, outerW)) { - FR.Add (IW); - myInternalWL.Remove( itIW ); // == itIW.Next() !!! - } - else - itIW.Next(); - } + FR.Add (IW); + myInternalWL.Remove( itIW ); // == itIW.Next() !!! + } + else + itIW.Next(); + } - // the hole-part of current pair of equal wires will be in the next new face - prevHolesL.Append ( it.Key() ); + // the hole-part of current pair of equal wires will be in the next new face + prevHolesL.Append ( it.Key() ); } // Loop on map of equal pairs searching for innermost wires // make faces FR.Perform(); if (FR.IsDone()) { - for (; FR.More(); FR.Next()) - myNewFaces.Append(FR.Current()); + for (; FR.More(); FR.Next()) + myNewFaces.Append(FR.Current()); } FR.Clear(); // add hole-parts to FaceRestrictor, - // remove themfrom the EqWM, + // remove them from the EqWM, // remove found wires as internal of resting classified wires Standard_Boolean clearOuterInner = ( prevHolesL.Extent() < EqWM.Extent() ); TopTools_ListIteratorOfListOfShape itPrev (prevHolesL); for (; itPrev.More(); itPrev.Next()) { - TopoDS_Wire& Hole = TopoDS::Wire ( itPrev.Value() ); - FR.Add ( Hole ); - if (clearOuterInner) { - const TopoDS_Wire& outerW = TopoDS::Wire ( EqWM.Find( Hole ) ); - // Loop on wires including outerW - TopTools_ListIteratorOfListOfShape itO( OuterInner.Ascendant( outerW )); - for (; itO.More(); itO.Next()) { - TopTools_ListOfShape& innerL = OuterInner.ChangeDescendant( itO.Value() ); - TopTools_ListIteratorOfListOfShape itI (innerL); - // Loop on internal wires of current including wire - for (; itI.More(); itI.Next()) - if ( outerW.IsSame( itI.Value() )) { - innerL.Remove( itI ); break; - } - } - } - EqWM.UnBind ( Hole ); + TopoDS_Wire& Hole = TopoDS::Wire ( itPrev.Value() ); + FR.Add ( Hole ); + if (clearOuterInner) { + const TopoDS_Wire& outerW = TopoDS::Wire ( EqWM.Find( Hole ) ); + // Loop on wires including outerW + TopTools_ListIteratorOfListOfShape itO( OuterInner.Ascendant( outerW )); + for (; itO.More(); itO.Next()) { + TopTools_ListOfShape& innerL = OuterInner.ChangeDescendant( itO.Value() ); + TopTools_ListIteratorOfListOfShape itI (innerL); + // Loop on internal wires of current including wire + for (; itI.More(); itI.Next()) + if ( outerW.IsSame( itI.Value() )) { + innerL.Remove( itI ); break; + } + } + } + EqWM.UnBind ( Hole ); + } + + if (nbEqW == EqWM.Extent()) + { + // error: pb with wires classification +#ifdef DEB + cout << "Partition_Loop2d::WiresToFaces(), pb with wires classification" << endl; +#endif + break; } } // while (!EqWM.IsEmpty) - } // !EqWM.IsEmpty() + } // if !EqWM.IsEmpty() myNewWires.Append ( myInternalWL ); @@ -1056,50 +1132,7 @@ void Partition_Loop2d::WiresToFaces(const BRepAlgo_Image& ) myNewFaces.Append(FR.Current()); - -#else // ifndef USE_BREPFEAT_SPLITSHAPE - - // ============================================================ - // use BRepFeat_SplitShape to make faces - // ============================================================ - - BRepFeat_SplitShape Split(myFace); - TopTools_MapOfShape AddedSectionEdgesMap; - - myNewWires.Append(myInternalWL); - - TopTools_ListIteratorOfListOfShape it(myNewWires); - for (; it.More(); it.Next()) { - TopoDS_Iterator itE(it.Value()); - for (; itE.More(); itE.Next()) { - const TopoDS_Edge& newE = TopoDS::Edge( itE.Value() ); - if (AddedSectionEdgesMap.Add(newE)) { - if (mySectionEdges.Contains(newE)) - Split.Add(newE,F); // new edge on face - else { - const TopoDS_Edge& oldE = TopoDS::Edge( EdgeImage.ImageFrom(newE) ); - Split.Add(newE, oldE); // splited edge - } - } - } - } - Split.Build(); - - if (Split.IsDone()) - myNewFaces = Split.Modified(F); - -#endif // ifndef USE_BREPFEAT_SPLITSHAPE - - - -#ifdef DEB - Standard_Integer nbF = myNewFaces.Extent(); - if (nbW != nbF) - cout << "WiresToFaces(): " << nbW << " wires --> " << myNewFaces.Extent() << " faces " - << endl; -#endif - TopTools_ListIteratorOfListOfShape itNF (myNewFaces); - for (; itNF.More(); itNF.Next()) + for (; itNF.More(); itNF.Next()) itNF.Value().Orientation( myFaceOri ); } diff --git a/src/PARTITION/Partition_Spliter.cdl b/src/PARTITION/Partition_Spliter.cdl index 252e94b0b..0fc9b5be5 100644 --- a/src/PARTITION/Partition_Spliter.cdl +++ b/src/PARTITION/Partition_Spliter.cdl @@ -94,6 +94,11 @@ is ---Category: private methods + MakeSolids (me: in out; Solid : Shape from TopoDS; + Shells: in out ListOfShape from TopTools) + is private; + ---Purpose: make solids out of Shells + MakeShells (me: in out; S : Shape from TopoDS; NS: in out ListOfShape from TopTools) is private; ---Purpose: split S into shells @@ -131,18 +136,39 @@ is -- shared by -- contains edge splits + IsInside (myclass; S1,S2 : Shape from TopoDS) + returns Boolean from Standard is private; + ---Purpose: Return True if the first vertex of S1 inside S2. + -- If S1.IsNull(), check infinite point against S2. + + GetOriginalShape(me; aShape : Shape from TopoDS) + returns Shape from TopoDS is private; + ---Purpose: Return the shape aShape originates from. aShape + -- should be a face or more complex result shape + + FindToolsToReconstruct(me: in out) is private; + ---Purpose: find and store as objects tools which interfere + -- with solids or are inside solids without + -- an interference + fields - myDoneStep : ShapeEnum from TopAbs; -- reconstructed topology + myDoneStep : ShapeEnum from TopAbs; -- rebuilt level myShape : Compound from TopoDS; -- result myBuilder : Builder from BRep; myListShapes : ListOfShape from TopTools; -- object shapes myMapFaces : MapOfShape from TopTools; -- object faces myMapTools : MapOfShape from TopTools; -- tool faces + myEqualEdges : MapOfShape from TopTools; -- equal splits + myNewSection : MapOfShape from TopTools; -- new secton edges + myClosedShapes : MapOfShape from TopTools; + myWrappingSolid: MapOfShape from TopTools; -- solids having other shapes inside myFaceShapeMap : DataMapOfShapeShape from TopTools; -- to find a shape by face - myNewSection : MapOfShape from TopTools; -- new secton edges + myInternalFaces: DataMapOfShapeShape from TopTools; -- shape and its internal faces + myIntNotClFaces: DataMapOfShapeShape from TopTools; -- internal but not closed + myAsDes : AsDes from BRepAlgo; myImagesFaces : Image from BRepAlgo; @@ -155,11 +181,4 @@ fields -- avoid rebuilding twice commont part of solids myAddedFacesMap: MapOfOrientedShape from TopTools; - -- equal splits - myEqualEdges : MapOfShape from TopTools; - - -- shape and its internal faces - myInternalFaces: DataMapOfShapeShape from TopTools; - myIntNotClFaces: DataMapOfShapeShape from TopTools;-- internal but not closed - end Spliter; diff --git a/src/PARTITION/Partition_Spliter.cxx b/src/PARTITION/Partition_Spliter.cxx index 502fbc956..8dd5d136d 100644 --- a/src/PARTITION/Partition_Spliter.cxx +++ b/src/PARTITION/Partition_Spliter.cxx @@ -27,18 +27,18 @@ // $Header$ using namespace std; -#include "Partition_Spliter.ixx" #include "Partition_Inter2d.hxx" #include "Partition_Inter3d.hxx" #include "Partition_Loop2d.hxx" #include "Partition_Loop3d.hxx" +#include "Partition_Spliter.ixx" #include "utilities.h" -#include -#include #include #include +#include +#include #include #include @@ -49,13 +49,13 @@ using namespace std; #include #include -#include -#include -#include #include #include #include #include +#include +#include +#include #include #include @@ -67,31 +67,41 @@ using namespace std; #include #include -#include -#include #include +#include +#include +#include -#include #include #include #include #ifdef DEB -#define DRAW 0 +//# define PART_PERF #endif -#ifdef DRAW -#include -Standard_IMPORT Standard_Boolean AffichInter3d ; -Standard_IMPORT Standard_Boolean AffichInter2d ; -Standard_IMPORT Standard_Boolean AffichVertex; -Standard_IMPORT Standard_Boolean AffichFace; -Standard_IMPORT Standard_Boolean AffichWire; -Standard_IMPORT Standard_Boolean SelectFace; +#ifdef PART_PERF +# include +#endif -static char* names = new char[100]; +//======================================================================= +//function : isClosed +//purpose : check id a shape is closed, ie is a solid or a closed shell +//======================================================================= -#endif +static Standard_Boolean isClosed(const TopoDS_Shape& theShape) +{ + Standard_Boolean isClosed = (theShape.ShapeType() == TopAbs_SOLID); + + if (!isClosed && theShape.ShapeType() == TopAbs_SHELL) { + TopTools_IndexedDataMapOfShapeListOfShape MEF; + TopExp::MapShapesAndAncestors(theShape, TopAbs_EDGE, TopAbs_FACE, MEF); + for (Standard_Integer i=1; isClosed && i<=MEF.Extent(); ++i) + isClosed = ( MEF(i).Extent() != 1 ); + } + + return isClosed; +} //======================================================================= //function : Partition_Spliter @@ -111,8 +121,23 @@ Partition_Spliter::Partition_Spliter() void Partition_Spliter::AddTool(const TopoDS_Shape& S) { + if (S.ShapeType() < TopAbs_SOLID) { // compound or compsolid + TopoDS_Iterator it (S); + for (; it.More(); it.Next()) + { + AddTool( it.Value()); + myFaceShapeMap.Bind( it.Value(), S ); // to know compound by shape + } + return; + } + for (TopExp_Explorer exp(S,TopAbs_FACE); exp.More(); exp.Next()) + { myMapTools.Add(exp.Current()); + myFaceShapeMap.Bind( exp.Current(), S ); + } + if (isClosed( S )) + myClosedShapes.Add( S ); } //======================================================================= @@ -125,7 +150,10 @@ void Partition_Spliter::AddShape(const TopoDS_Shape& S) if (S.ShapeType() < TopAbs_SOLID) { // compound or compsolid TopoDS_Iterator it (S); for (; it.More(); it.Next()) + { AddShape( it.Value()); + myFaceShapeMap.Bind( it.Value(), S ); // to know compound by shape + } return; } @@ -134,14 +162,28 @@ void Partition_Spliter::AddShape(const TopoDS_Shape& S) //myBuilder.Add( myShape, S ); return; } - - myListShapes.Append(S); + Standard_Integer nbFacesBefore = myMapFaces.Extent(); // not to add twice the same S for (; exp.More(); exp.Next()) { - myFaceShapeMap.Bind( exp.Current(), S ); - myMapFaces.Add(exp.Current()); - myImagesFaces.SetRoot(exp.Current()); + const TopoDS_Shape & aFace = exp.Current(); + if ( ! myFaceShapeMap.IsBound( aFace )) // keep shape of tool face added as object + myFaceShapeMap.Bind( aFace, S ); + if (myMapFaces.Add( aFace )) + myImagesFaces.SetRoot( aFace ); } + + if (nbFacesBefore == myMapFaces.Extent()) + return; + + // solids must be processed before all + if (S.ShapeType() == TopAbs_SOLID) + myListShapes.Prepend(S); + else + myListShapes.Append(S); + + if (isClosed( S )) + myClosedShapes.Add( S ); + } //======================================================================= @@ -166,9 +208,14 @@ void Partition_Spliter::Clear() myListShapes.Clear(); myMapFaces.Clear(); myMapTools.Clear(); + myClosedShapes.Clear(); + myEqualEdges.Clear(); + myNewSection.Clear(); + myWrappingSolid.Clear(); myFaceShapeMap.Clear(); - myNewSection.Clear(); + myInternalFaces.Clear(); + myIntNotClFaces.Clear(); myAsDes->Clear(); myImagesFaces.Clear(); @@ -179,7 +226,6 @@ void Partition_Spliter::Clear() myAddedFacesMap.Clear(); - myInternalFaces.Clear(); } //======================================================================= @@ -199,6 +245,10 @@ void Partition_Spliter::Compute(const TopAbs_ShapeEnum Limit) TopTools_ListIteratorOfListOfShape itl; TopExp_Explorer exp; +#ifdef PART_PERF + OSD_Chronometer aCron; +#endif + if (myDoneStep > TopAbs_VERTEX) { TopTools_ListOfShape aListFaces; @@ -206,102 +256,38 @@ void Partition_Spliter::Compute(const TopAbs_ShapeEnum Limit) for (it.Initialize(myMapTools); it.More(); it.Next()) aListFaces.Append(it.Key()); +#ifdef PART_PERF + aCron.Start(); +#endif + //----------------------------------------------- // Intersection between faces //----------------------------------------------- // result is in myAsDes as a map Face - list of new edges; // special care is done for section edges, same domain faces and vertices: // data about them is inside myInter3d - myInter3d.CompletPart3d(aListFaces, myFaceShapeMap); - TopTools_MapOfShape& Modif = myInter3d.TouchedFaces(); - TopTools_MapOfShape& NewEdges = myInter3d.NewEdges(); - Handle(BRepAlgo_AsDes) SectionEdgesAD = myInter3d.SectionEdgesAD(); - -#ifdef DRAW - if (AffichInter3d) { - Standard_Integer i=0; - for (it.Initialize(NewEdges); it.More(); it.Next(), i++) { - sprintf(names,"e_%d",i); - cout << "donly " << names << endl; - DBRep::Set(names,it.Key()); - } - } +#ifdef PART_PERF + cout << "+++ CompletPart3d()" << endl; + aCron.Show( cout ); + aCron.Reset(); + aCron.Start(); #endif - //if (Modif.IsEmpty()) return; - - // ----------------------------------------------- - // store tools intersecting solids as object shapes, - // they must split into faces too - // ----------------------------------------------- - - // build edge - face map for tool faces - TopTools_IndexedDataMapOfShapeListOfShape EFM; - for (it.Initialize(myMapTools); it.More(); it.Next()) - TopExp::MapShapesAndAncestors( it.Key(), TopAbs_EDGE, TopAbs_FACE, EFM); - - TopTools_MapOfShape checkedEdgeMap; - for (itl.Initialize( myListShapes ); itl.More(); itl.Next()) { - TopExp_Explorer expSo (itl.Value(), TopAbs_SOLID); - for (; expSo.More(); expSo.Next()) { - - TopTools_ListOfShape checkFL; // faces to check - for ( exp.Init( expSo.Current(), TopAbs_FACE); exp.More(); exp.Next()) - checkFL.Append ( exp.Current()); - - // iterate a list while appending new items - TopTools_ListIteratorOfListOfShape itF, itCF; - for (itCF.Initialize (checkFL) ; itCF.More(); itCF.Next()) { - const TopoDS_Shape& F = itCF.Value(); - if ( myAsDes->HasDescendant( F )) { - // new edges on face to check - const TopTools_ListOfShape& NEL = myAsDes->Descendant( F ); - TopTools_ListIteratorOfListOfShape itE (NEL); - for (; itE.More(); itE.Next()) { - if (checkedEdgeMap.Add( itE.Value() )) { - // intersected faces originating an edge - itF.Initialize (myAsDes->Ascendant( itE.Value() )); - for (; itF.More(); itF.Next()) { - if (!myMapFaces.Contains( itF.Value())) { - AddShape( itF.Value() ); - checkFL.Append( itF.Value() ); - } - } - // faces having section edges on F - if (EFM.Contains( itE.Value())) - itF.Initialize ( EFM.FindFromKey (itE.Value())); - for (; itF.More(); itF.Next()) { - if (!myMapFaces.Contains( itF.Value())) { - AddShape( itF.Value() ); - checkFL.Append( itF.Value() ); - } - } - } - } - } - // find faces cut by edges of F - TopExp_Explorer expE(F, TopAbs_EDGE); - for (; expE.More();expE.Next()) { - if ( SectionEdgesAD->HasAscendant( expE.Current() ) - && checkedEdgeMap.Add( expE.Current() )) { - itF.Initialize( SectionEdgesAD->Ascendant( expE.Current()) ); - for (; itF.More(); itF.Next()) { - if (!myMapFaces.Contains( itF.Value())) { - AddShape( itF.Value() ); - checkFL.Append( itF.Value() ); - } - } - } - } - } - } - } - //----------------------------------------------- // Intersection of edges //----------------------------------------------- + // add tool faces which must be reconstructed to myMapFaces too + FindToolsToReconstruct(); + +#ifdef PART_PERF + cout << "+++ FindToolsToReconstruct()" << endl; + aCron.Show( cout ); + aCron.Reset(); + aCron.Start(); +#endif + // add existing vertices to edges of object faces in myAsDes TopTools_MapOfShape DoneEM; for ( it.Initialize(myMapFaces); it.More(); it.Next()) { @@ -321,15 +307,22 @@ void Partition_Spliter::Compute(const TopAbs_ShapeEnum Limit) } // intersect edges that are descendants of a face in myAsDes + TopTools_MapOfShape& Modif = myInter3d.TouchedFaces(); for ( it.Initialize(Modif); it.More(); it.Next()) { const TopoDS_Face& F = TopoDS::Face(it.Key()); - Partition_Inter2d::CompletPart2d (myAsDes, F, NewEdges); + Partition_Inter2d::CompletPart2d (myAsDes, F, myInter3d.NewEdges()); } // now myAsDes contains also new vertices made at edge intersection as // descendant of edges both new and old myDoneStep = TopAbs_VERTEX; +#ifdef PART_PERF + cout << "+++ CompletPart2d()" << endl; + aCron.Show( cout ); + aCron.Reset(); + aCron.Start(); +#endif } // if (myDoneStep > TopAbs_VERTEX) if (Limit == TopAbs_VERTEX) { @@ -344,17 +337,20 @@ void Partition_Spliter::Compute(const TopAbs_ShapeEnum Limit) return; } + if (myDoneStep > TopAbs_EDGE) { //----------------------------------------------- - // Reconstruction of all the edges. + //----------------------------------------------- + // ------- Reconstruction of all the edges.------ + //----------------------------------------------- //----------------------------------------------- - // Add to myAsDes end vertices of new edges and cut new edges - int j=1; - TopTools_MapOfShape& NewEdges = myInter3d.NewEdges(); + // ============== + // cut new edges + // ============== TopTools_ListOfShape LSE; // all edge splits - for ( it.Initialize(NewEdges); it.More(); it.Next()) { + for ( it.Initialize(myInter3d.NewEdges()); it.More(); it.Next()) { TopoDS_Vertex V1,V2; TopoDS_Edge EE = TopoDS::Edge(it.Key()); @@ -366,9 +362,11 @@ void Partition_Spliter::Compute(const TopAbs_ShapeEnum Limit) if (aListV.IsEmpty()) continue; // new edge does not intersect any other edge - // one face is Tool, the other is Shape: - if ( (myMapTools.Contains(aListF.First()) && myMapFaces.Contains(aListF.Last()) ) || - ( myMapFaces.Contains(aListF.First()) && myMapTools.Contains(aListF.Last()) ) ) + // Add end vertices to new edges only if + // one face is Tool and the other is Shape + Standard_Boolean isTool1 = ! myMapFaces.Contains( aListF.First() ); + Standard_Boolean isTool2 = ! myMapFaces.Contains( aListF.Last() ); + if (isTool1 || isTool2) { TopExp::Vertices(EE,V1,V2); Standard_Real Tol = Max (BRep_Tool::Tolerance( V1 ), @@ -402,19 +400,10 @@ void Partition_Spliter::Compute(const TopAbs_ShapeEnum Limit) myAsDes->Add(EE,V2); } } -#ifdef DRAW - if (AffichVertex) { - for(itl.Initialize(aListV);itl.More();itl.Next(), j++) { - sprintf(names,"v_%d",j); - cout << "donly " << names << endl; - DBRep::Set(names,itl.Value()); - } - } -#endif + // cut new edges Standard_Integer NbV=aListV.Extent() ; if (NbV>1 || (NbV==1 && V1.IsSame(V2)) ) { - // cut new edges TopTools_ListOfShape LNE; MakeEdges (EE,aListV, LNE); myImagesEdges.Bind(EE,LNE); @@ -422,7 +411,9 @@ void Partition_Spliter::Compute(const TopAbs_ShapeEnum Limit) } } + // ============== // cut old edges + // ============== for ( it.Initialize(myMapFaces); it.More(); it.Next()) { for (exp.Init( it.Key(), TopAbs_EDGE); exp.More(); exp.Next()) { const TopoDS_Edge& EE = TopoDS::Edge( exp.Current() ); @@ -435,17 +426,32 @@ void Partition_Spliter::Compute(const TopAbs_ShapeEnum Limit) LSE.Append( LNE ); } } +#ifdef PART_PERF + cout << "+++ Cut Edges" << endl; + aCron.Show( cout ); + aCron.Reset(); + aCron.Start(); +#endif + // process same domain section edges MergeEqualEdges( LSE ); myDoneStep = TopAbs_EDGE; +#ifdef PART_PERF + cout << "+++ MergeEqualEdges()" << endl; + aCron.Show( cout ); + aCron.Reset(); + aCron.Start(); +#endif } // if (myDoneStep > TopAbs_EDGE) if (Limit == TopAbs_EDGE) { // add splits of old edges TopTools_ListIteratorOfListOfShape itNE; for (itl.Initialize( myListShapes );itl.More();itl.Next()) { + if (myMapTools.Contains( itl.Value() )) + continue; // skip tool faces for ( exp.Init( itl.Value(), TopAbs_EDGE ); exp.More(); exp.Next()) { itNE.Initialize( myImagesEdges.Image( exp.Current() )); for ( ; itNE.More(); itNE.Next()) @@ -461,9 +467,6 @@ void Partition_Spliter::Compute(const TopAbs_ShapeEnum Limit) return; } - // make faces interfering by section edges share the same splits - //ProcessSectionEdges( SectionEdgesAD ); - //----------------------------------------------- // split faces @@ -480,6 +483,12 @@ void Partition_Spliter::Compute(const TopAbs_ShapeEnum Limit) } myDoneStep = TopAbs_FACE; +#ifdef PART_PERF + cout << "+++ MakeFaces()" << endl; + aCron.Show( cout ); + aCron.Reset(); + aCron.Start(); +#endif } if (Limit == TopAbs_WIRE || @@ -496,203 +505,128 @@ void Partition_Spliter::Compute(const TopAbs_ShapeEnum Limit) //----------------------------------------------- - // split solids + // split and add solids and shells //----------------------------------------------- - - // solids must remains closed, so process them first + Standard_Boolean makeSolids = (Limit == TopAbs_SHAPE || Limit < TopAbs_SHELL); + for (itl.Initialize(myListShapes);itl.More();itl.Next()) + { + const TopoDS_Shape & S = itl.Value(); + if (S.ShapeType() > TopAbs_SHELL) + continue; - for (itl.Initialize(myListShapes);itl.More();itl.Next()) { - if (itl.Value().ShapeType() == TopAbs_SOLID) { - TopTools_ListOfShape NSL; - MakeShells (itl.Value() , NSL); - TopTools_ListIteratorOfListOfShape itS(NSL); - for ( ; itS.More(); itS.Next()) - if (makeSolids) { - // make a solid from a shell - TopoDS_Solid Solid; - myBuilder.MakeSolid( Solid ); - myBuilder.Add (Solid, itS.Value()); - myBuilder.Add (myShape, Solid); - } - else - myBuilder.Add (myShape, itS.Value()); - } + TopTools_ListOfShape NSL; // new shape list + MakeShells (S , NSL); + if (makeSolids && S.ShapeType() == TopAbs_SOLID ) + MakeSolids( S, NSL ); + + TopTools_ListIteratorOfListOfShape itNSL (NSL); + for ( ; itNSL.More(); itNSL.Next()) + myBuilder.Add (myShape, itNSL.Value()); } - - //----------------------------------------------- - // split shells - //----------------------------------------------- +#ifdef PART_PERF + cout << "+++ MakeShells()" << endl; + aCron.Show( cout ); +#endif - for (itl.Initialize(myListShapes);itl.More();itl.Next()) { - if (itl.Value().ShapeType() == TopAbs_SHELL) { - TopTools_ListOfShape NSL; - MakeShells (itl.Value() , NSL); - TopTools_ListIteratorOfListOfShape itS(NSL); - for ( ; itS.More(); itS.Next()) - myBuilder.Add (myShape, itS.Value()); - } - } - //----------------------------------------------- // add split faces //----------------------------------------------- - for (itl.Initialize(myListShapes);itl.More();itl.Next()) { - const TopoDS_Shape& S = itl.Value(); + for (itl.Initialize(myListShapes);itl.More();itl.Next()) + { + const TopoDS_Shape & S = itl.Value(); if (S.ShapeType() != TopAbs_FACE || - myMapTools.Contains( S )) + myMapTools.Contains( S )) continue; TopoDS_Iterator itS( myImageShape.Image(S).First() ); for (; itS.More(); itS.Next()) if (! myAddedFacesMap.Contains( itS.Value() )) - myBuilder.Add (myShape, itS.Value()); + myBuilder.Add (myShape, itS.Value()); } - + myDoneStep = makeSolids ? TopAbs_SOLID : TopAbs_SHELL; } - -//======================================================================= -//function : Tri -//purpose : -//======================================================================= - -static void Tri(const TopoDS_Edge& E, - TopTools_SequenceOfShape& Seq) -{ - Standard_Boolean Invert = Standard_True; - Standard_Integer NbPoints = Seq.Length(); - Standard_Real U1,U2; - TopoDS_Vertex V1,V2; - - while (Invert) { - Invert = Standard_False; - for ( Standard_Integer i = 1; i < Seq.Length(); i++) { - - V1 = TopoDS::Vertex(Seq.Value(i)); - V2 = TopoDS::Vertex(Seq.Value(i+1)); - - V1.Orientation(TopAbs_INTERNAL); - V2.Orientation(TopAbs_INTERNAL); - - U1 = BRep_Tool::Parameter(V1,E); - U2 = BRep_Tool::Parameter(V2,E); - - if (IsEqual(U1,U2)) { - Seq.Remove(i); - i--; - continue; - } - if (U2 < U1) { - Seq.Exchange(i,i+1); - Invert = Standard_True; - } - } - } -} - //======================================================================= -//function : MakeEdges -//purpose : cut E by vertices VOnE, return list of new edges NE +//function : MakeSolids +//purpose : make solids out of Shells //======================================================================= -void Partition_Spliter::MakeEdges (const TopoDS_Edge& E, - const TopTools_ListOfShape& VOnE, - TopTools_ListOfShape& NE ) const +void Partition_Spliter::MakeSolids(const TopoDS_Shape & theSolid, + TopTools_ListOfShape & theShellList) { - TopoDS_Edge WE = E; - WE.Orientation(TopAbs_FORWARD); + // for a solid wrapping other shells or solids without intersection, + // it is necessary to find shells making holes in it - TopTools_ListIteratorOfListOfShape itv(VOnE); - TopTools_SequenceOfShape SV; + TopTools_ListOfShape aNewSolids; // result + TopTools_ListOfShape aHoleShells; + TopoDS_Shape anInfinitePointShape; - Standard_Real U1,U2, f, l; - TopoDS_Vertex V1,V2,VF,VL; + Standard_Boolean isWrapping = myWrappingSolid.Contains( theSolid ); + if (!isWrapping && !theShellList.IsEmpty()) + { + // check if theSolid initially has internal shells + TopoDS_Iterator aShellExp (theSolid); + aShellExp.Next(); + isWrapping = aShellExp.More(); + } + + TopTools_ListIteratorOfListOfShape aShellIt(theShellList); + for ( ; aShellIt.More(); aShellIt.Next()) + { + const TopoDS_Shape & aShell = aShellIt.Value(); - BRep_Tool::Range(WE,f,l); - TopExp::Vertices(WE,VF,VL); + // check if a shell is a hole + if (isWrapping && IsInside (anInfinitePointShape, aShell)) + aHoleShells.Append( aShell ); + else + { + // make a solid from a shell + TopoDS_Solid Solid; + myBuilder.MakeSolid( Solid ); + myBuilder.Add (Solid, aShell); - if (VOnE.Extent() < 3) { // do not rebuild not cut edge - if (( VF.IsSame( VOnE.First() ) && VL.IsSame( VOnE.Last() )) || - VL.IsSame( VOnE.First() ) && VF.IsSame( VOnE.Last() ) ) { - NE.Append( E ); - return; + aNewSolids.Append (Solid); } } - for (; itv.More(); itv.Next()) - SV.Append(itv.Value()); - - Tri( WE, SV); - - Standard_Integer iVer, NbVer = SV.Length(); - - - //---------------------------------------------------------------- - // Construction of the new edges . - //---------------------------------------------------------------- + // find outer a shell most close to each hole shell + TopTools_DataMapOfShapeShape aInOutMap; + for (aShellIt.Initialize( aHoleShells ); aShellIt.More(); aShellIt.Next()) + { + const TopoDS_Shape & aHole = aShellIt.Value(); + TopTools_ListIteratorOfListOfShape aSolisIt (aNewSolids); + for ( ; aSolisIt.More(); aSolisIt.Next()) + { + const TopoDS_Shape & aSolid = aSolisIt.Value(); + if (! IsInside( aHole, aSolid )) + continue; - if (VF.IsSame(VL)) { // closed edge - if (NbVer==1) - SV.Append( SV.First() ); - else if (!SV.First().IsSame(SV.Last())) { - Standard_Boolean isFirst=0; - Standard_Real minDU = 1.e10; - TopoDS_Vertex endV = Partition_Inter2d::FindEndVertex(VOnE, f,l, E, isFirst,minDU); - if (endV.IsSame(SV.First())) - SV.Append(endV); - else if (endV.IsSame(SV.Last())) - SV.Prepend(endV); + if ( aInOutMap.IsBound (aHole)) + { + const TopoDS_Shape & aSolid2 = aInOutMap( aHole ); + if ( IsInside( aSolid, aSolid2 )) + { + aInOutMap.UnBind( aHole ); + aInOutMap.Bind ( aHole, aSolid ); + } + } else - MESSAGE ("END VERTEX IS IN SEQUNCE MIDDLE"); - } - NbVer = SV.Length(); - } - - for (iVer=1; iVer < NbVer; iVer++) { - V1 = TopoDS::Vertex(SV(iVer)); - V2 = TopoDS::Vertex(SV(iVer+1)); - - TopoDS_Shape NewEdge = WE.EmptyCopied(); - V1.Orientation(TopAbs_FORWARD); - myBuilder.Add (NewEdge,V1); - V2.Orientation(TopAbs_REVERSED); - myBuilder.Add (NewEdge,V2); - - if (iVer==1) - U1 = f; - else { - V1.Orientation(TopAbs_INTERNAL); - U1=BRep_Tool::Parameter(V1,WE); - } - if (iVer+1 == NbVer) - U2 = l; - else { - V2.Orientation(TopAbs_INTERNAL); - U2=BRep_Tool::Parameter(V2,WE); - } - if (Abs(U1-U2) <= Precision::PConfusion()) { - MESSAGE( "MakeEdges(), EQUAL PARAMETERS OF DIFFERENT VERTICES"); - continue; + aInOutMap.Bind ( aHole, aSolid ); } - TopoDS_Edge EE=TopoDS::Edge(NewEdge); - myBuilder.Range (EE,U1,U2); - TopoDS_Edge NEdge = TopoDS::Edge(NewEdge); - myBuilder.SameParameter(NEdge,Standard_False); - - Standard_Real tol = 1.0e-2; - Standard_Boolean flag = BRep_Tool::SameParameter(NEdge); - if (!flag) { - BRepLib::SameParameter(NEdge,tol); - } - NE.Append(NEdge.Oriented(E.Orientation())); + // add aHole to a solid + if (aInOutMap.IsBound( aHole )) + myBuilder.Add ( aInOutMap( aHole ), aHole ); } -} + theShellList.Clear(); + theShellList.Append( aNewSolids ); +} + //======================================================================= //function : FindFacesInside //purpose : return compound of faces of other shapes that are @@ -707,6 +641,9 @@ TopoDS_Shape Partition_Spliter::FindFacesInside(const TopoDS_Shape& theShape, const Standard_Boolean CheckClosed, const Standard_Boolean All) { + // ================================================ + // check if internal faces have been already found + // ================================================ TopExp_Explorer expl; if (myInternalFaces.IsBound( theShape )) { @@ -728,6 +665,10 @@ TopoDS_Shape Partition_Spliter::FindFacesInside(const TopoDS_Shape& theShape, return C; } + // =================================== + // get data for internal faces search + // =================================== + // compound of split faces of theShape const TopoDS_Shape& CSF = myImageShape.Image(theShape).First(); @@ -738,7 +679,7 @@ TopoDS_Shape Partition_Spliter::FindFacesInside(const TopoDS_Shape& theShape, // MSE filling: map of new section edges of CSF for (expl.Init(CSF,TopAbs_EDGE); expl.More(); expl.Next()) { - TopoDS_Shape resE = expl.Current() ; + const TopoDS_Shape & resE = expl.Current() ; if (myNewSection.Contains( resE )) // only new edges MSE.Add(resE); } @@ -774,7 +715,28 @@ TopoDS_Shape Partition_Spliter::FindFacesInside(const TopoDS_Shape& theShape, } } + // add tool faces having section edges on faces of theShape to MFP and DMSEFP; + // such tool faces need not to be reconstructed and so they are not in myListShapes + for (itm.Initialize(myMapTools); itm.More(); itm.Next()) + { + const TopoDS_Shape & aToolFace = itm.Key(); + if (myMapFaces.Contains( aToolFace )) + continue; + MFP.Add(aToolFace); + for (expl.Init( aToolFace, TopAbs_EDGE ); expl.More(); expl.Next()) { + TopoDS_Shape se = expl.Current(); + if ( MSE.Contains( se )) {// section edge + if (!DMSEFP.IsBound( se )) + DMSEFP.Bind( se, EmptyL ); + DMSEFP( se ).Append( aToolFace ); + } + } + } + + + // =========================== // find faces inside theShape + // =========================== Standard_Boolean skipAlreadyAdded = Standard_False; Standard_Boolean GoodOri, inside; @@ -789,7 +751,7 @@ TopoDS_Shape Partition_Spliter::FindFacesInside(const TopoDS_Shape& theShape, const TopoDS_Edge& E = TopoDS::Edge (Mapit.Key()); // an original edge of which E is a split const TopoDS_Edge& OrigE = TopoDS::Edge ( myImagesEdges.Root( E )); - // is OrigE itself splits a face + // does OrigE itself splits a face Standard_Boolean isSectionE = myInter3d.IsSectionEdge ( OrigE ); // split faces of other shapes sharing E @@ -813,7 +775,9 @@ TopoDS_Shape Partition_Spliter::FindFacesInside(const TopoDS_Shape& theShape, // find another face which originates from the same face as aFace1: // usually aFace2 is internal if aFace1 is not and vice versa - const TopoDS_Shape& anOrigFace = myImagesFaces.Root(aFace1); + TopoDS_Shape anOrigFace = aFace1; + if (myImagesFaces.IsImage(aFace1)) + anOrigFace = myImagesFaces.Root(aFace1); TopoDS_Shape aFace2; if ( !isSectionE ) { while (itl.More()) { @@ -863,14 +827,24 @@ TopoDS_Shape Partition_Spliter::FindFacesInside(const TopoDS_Shape& theShape, // keep one of found faces - //face of CSF sharing E + //face of CSF sharing E const TopoDS_Shape& aShapeFace = sameDom1 ? FL.Last() : FL.First(); // analyse aFace1 state inside = Partition_Loop3d::IsInside (E, TopoDS::Face(aShapeFace), aFace1, 1, dot, GoodOri); + if (inside && isSectionE) + { + // aFace1 must be tested with both adjacent faces of CSF + const TopoDS_Shape& aShapeFace2 = sameDom1 ? FL.First() : FL.Last(); + if (aShapeFace2 != aShapeFace) + inside = Partition_Loop3d::IsInside (E, TopoDS::Face(aShapeFace2), aFace1, + 1, dot, GoodOri); + } + // store internal face if (inside) - KeepFaces.Append(aFace1); + KeepFaces.Append(aFace1); + else if (!aFace2.IsNull()) { if (dot + Precision::Angular() >= 1.0) @@ -881,12 +855,14 @@ TopoDS_Shape Partition_Spliter::FindFacesInside(const TopoDS_Shape& theShape, LSF.Append( aFace2 ); } else - KeepFaces.Append(aFace2); + KeepFaces.Append(aFace2); } } } + // =================================================== // add not distributed faces connected with KeepFaces + // =================================================== // ultimate list of internal faces TopTools_ListOfShape KeptFaces; @@ -927,21 +903,86 @@ TopoDS_Shape Partition_Spliter::FindFacesInside(const TopoDS_Shape& theShape, } } - // check if kept faces form a shell without free edges + // =============================================================== + // here MFP contains faces outer of theShape and those of shapes + // which do not interfere with theShape at all and between which + // there may be those wrapped by theShape and whose faces may be + // needed to be returned as well + // =============================================================== - DMEF.Clear(); // edge - kept faces - MFP.Clear(); // wrong faces - if (CheckClosed) { - for (itl.Initialize(KeptFaces); itl.More(); itl.Next() ) - TopExp::MapShapesAndAncestors(itl.Value(), TopAbs_EDGE, TopAbs_FACE, DMEF); + Standard_Boolean isSolid = (theShape.ShapeType() == TopAbs_SOLID); + if (All || isSolid) // All is for sub-result removal + { + for ( itm.Initialize( MFP ); itm.More(); itm.Next() ) { + TopoDS_Shape aFace = itm.Key(); - Standard_Integer i, nb = DMEF.Extent(); - Standard_Boolean isClosed = Standard_False; - while (!isClosed) { + // find a shape aFace originates from + TopoDS_Shape anOrigShape = GetOriginalShape( aFace ); + + // find out if all faces of anOrigShape are not in MFP + // and by the way remove them from MFP + Standard_Boolean isAllOut = Standard_True; + TopoDS_Shape aSplitFaces = anOrigShape; + if (myImageShape.HasImage(anOrigShape)) + aSplitFaces = myImageShape.Image(anOrigShape).First(); + + TopTools_ListOfShape aSplitFaceL; + for (expl.Init( aSplitFaces, TopAbs_FACE ); expl.More(); expl.Next()) + { + const TopoDS_Shape & aSpFace = expl.Current(); + // a tool face which become object has image but the whole tool shape has not + if (myImageShape.HasImage( aSpFace )) + { + TopExp_Explorer exF (myImageShape.Image( aSpFace ).First(), TopAbs_FACE ); + for ( ; exF.More(); exF.Next() ) + { + aSplitFaceL.Append( exF.Current() ); + if ( ! MFP.Remove( exF.Current() )) + isAllOut = Standard_False; + } + } + else + { + aSplitFaceL.Append( aSpFace ); + if ( ! MFP.Remove( aSpFace )) + isAllOut = Standard_False; + } + } + itm.Initialize( MFP ); + if ( !isAllOut ) + continue; + + // classify anOrigShape against theShape + if (IsInside (anOrigShape, theShape)) + { + if (isSolid && myClosedShapes.Contains( anOrigShape )) + // to make a special care at solid reconstruction + myWrappingSolid.Add ( theShape ); + + // keep faces of an internal shape anOrigShape + KeptFaces.Append( aSplitFaceL ); + } + } + } + + // ==================================================== + // check if kept faces form a shell without free edges + // ==================================================== + + DMEF.Clear(); // edge - kept faces + MFP.Clear(); // reuse it for wrong faces + if (CheckClosed) { + for (itl.Initialize(KeptFaces); itl.More(); itl.Next() ) + TopExp::MapShapesAndAncestors(itl.Value(), TopAbs_EDGE, TopAbs_FACE, DMEF); + + Standard_Integer i, nb = DMEF.Extent(); + Standard_Boolean isClosed = Standard_False; + while (!isClosed) { isClosed = Standard_True; for (i=1; isClosed && i<=nb; ++i) { const TopoDS_Shape& E = DMEF.FindKey( i ); - if (! MSE.Contains( E )) + if (! BRep_Tool::Degenerated( TopoDS::Edge( E )) && + ! MSE.Contains( E )) isClosed = ( DMEF(i).Extent() != 1 ); } if (!isClosed) { @@ -962,7 +1003,10 @@ TopoDS_Shape Partition_Spliter::FindFacesInside(const TopoDS_Shape& theShape, } } - // a result compound + // ============== + // make a result + // ============== + TopoDS_Compound C; // compound of removed internal faces TopoDS_Compound CNotCl; @@ -997,77 +1041,35 @@ TopoDS_Shape Partition_Spliter::FindFacesInside(const TopoDS_Shape& theShape, void Partition_Spliter::MakeShells(const TopoDS_Shape& S, TopTools_ListOfShape& NS) { - // check if S is closed shape - Standard_Boolean isClosed = Standard_True; - - TopTools_IndexedDataMapOfShapeListOfShape MEF; - Standard_Integer i; - if (S.ShapeType() != TopAbs_SOLID) { - TopExp::MapShapesAndAncestors(S, TopAbs_EDGE, TopAbs_FACE, MEF); - for (i=1; isClosed && i<=MEF.Extent(); ++i) - isClosed = ( MEF(i).Extent() != 1 ); - } Partition_Loop3d ShellMaker; // get compound of split faces of S const TopoDS_Shape& FacesComp = myImageShape.Image(S).First(); ShellMaker.AddConstFaces( FacesComp ); - // split faces inside S - if (isClosed) { + // add split faces inside S + if (myClosedShapes.Contains( S )) { TopoDS_Shape InternalFacesComp = FindFacesInside(S, Standard_True); ShellMaker.AddSectionFaces( InternalFacesComp ); -// } else { // a shell may become closed -// ShellMaker.AddConstFaces( InternalFacesComp ); } NS = ShellMaker.MakeShells( myAddedFacesMap ); - // 1. Add faces added to new shell to myAddedFacesMap: + // Add faces added to new shell to myAddedFacesMap: // avoid rebuilding twice commont part of 2 solids. - // 2. Check shell closeness (DEBUG) TopTools_ListIteratorOfListOfShape itS(NS); while ( itS.More()) { -#ifdef DEB - Standard_Boolean checkCloseness = Standard_True; -#endif TopExp_Explorer expF (itS.Value(), TopAbs_FACE); - for (; expF.More(); expF.Next()) { - + for (; expF.More(); expF.Next()) myAddedFacesMap.Add (expF.Current()); - -#ifdef DEB - if (checkCloseness && - ! myInter3d.HasSameDomainF( myImagesFaces.Root(expF.Current()) )) - checkCloseness = Standard_False; -#endif - } -#ifdef DEB - if (checkCloseness) { - // if S is closed, a new shell must be closed too; - if (isClosed) { - // check that a new shell is closed - MEF.Clear(); - TopExp::MapShapesAndAncestors(itS.Value(), TopAbs_EDGE, TopAbs_FACE, MEF); - for (i=1; isClosed && i<=MEF.Extent(); ++i) - isClosed = ( MEF(i).Extent() != 1 ); - if (!isClosed) { // remove not closed shell - MESSAGE (" NOT CLOSED SHELL " ); - //NS.Remove( itS ); - itS.Next(); - continue; - } - } - } -#endif itS.Next(); - } // loop on new shells + } } //======================================================================= //function : findEqual -//purpose : compare edges form EL1 against edges from EL2, -// Result is in EMM binding edge form EL1 to list of equal edges -// Edges are considered equall only if they have same vertices +//purpose : compare edges of EL1 against edges of EL2, +// Result is in EMM binding EL1 edges to list of equal edges. +// Edges are considered equall only if they have same vertices. // ==True makes consider same edges as equal // Put in all equal edges //======================================================================= @@ -1111,7 +1113,7 @@ static void findEqual (const TopTools_ListOfShape& EL1, itE2.Initialize( VEM(V1) ); for (; itE2.More(); itE2.Next()) { const TopoDS_Edge& E2 = TopoDS::Edge( itE2.Value()); - if (BRep_Tool::Degenerated( E2 )) + if (BRep_Tool::Degenerated( E2 ) || AllEqMap.Contains (E2)) continue; if (E1.IsSame(E2)) { @@ -1207,7 +1209,7 @@ TopoDS_Shape Partition_Spliter::MakeFaces (const TopoDS_Shape& S) TopTools_IndexedMapOfShape EM; TopExp::MapShapes( F, TopAbs_EDGE, EM); - TopTools_MapOfShape AddedEqualM; + TopTools_MapOfShape AddedEqualM, EqualSeamM; Standard_Boolean needRebuild = Standard_False; // add splits to loops @@ -1230,8 +1232,11 @@ TopoDS_Shape Partition_Spliter::MakeFaces (const TopoDS_Shape& S) Standard_Boolean isSameE = NE.IsSame ( E ); if ( isNewE || isSectionE || !isSameE) { - if (AddedEqualM.Contains( NE )) - continue; + if (AddedEqualM.Contains( NE )) { + // a seam must be twice in a loop + if (!BRep_Tool::IsClosed( E, F ) || !EqualSeamM.Add( NE )) + continue; + } if (isNewE) { if (isSectionE) { @@ -1266,8 +1271,8 @@ TopoDS_Shape Partition_Spliter::MakeFaces (const TopoDS_Shape& S) } } } - if (myEqualEdges.Contains( NE ) && !AddedEqualM.Add( NE )) - continue; + if (myEqualEdges.Contains( NE )) + AddedEqualM.Add( NE ); needRebuild = Standard_True; } @@ -1370,6 +1375,157 @@ TopoDS_Shape Partition_Spliter::MakeFaces (const TopoDS_Shape& S) return C; } + +//======================================================================= +//function : Tri +//purpose : +//======================================================================= + +static void Tri(const TopoDS_Edge& E, + TopTools_SequenceOfShape& Seq, + const Partition_Inter3d & theInter3d) +{ + Standard_Boolean Invert = Standard_True; + Standard_Real U1,U2; + TopoDS_Vertex V1,V2; + + while (Invert) { + Invert = Standard_False; + for ( Standard_Integer i = 1; i < Seq.Length(); i++) { + + V1 = TopoDS::Vertex(Seq.Value(i)); + V2 = TopoDS::Vertex(Seq.Value(i+1)); + + V1.Orientation(TopAbs_INTERNAL); + V2.Orientation(TopAbs_INTERNAL); + + U1 = BRep_Tool::Parameter(V1,E); + U2 = BRep_Tool::Parameter(V2,E); + + if (IsEqual(U1,U2)) { + if (theInter3d.ReplaceSameDomainV( V1, E ).IsSame( V1 )) + Seq.Remove(i+1); // remove V2 + else + Seq.Remove(i); + i--; + continue; + } + if (U2 < U1) { + Seq.Exchange(i,i+1); + Invert = Standard_True; + } + } + } +} + +//======================================================================= +//function : MakeEdges +//purpose : cut E by vertices VOnE, return list of new edges NE +//======================================================================= + +void Partition_Spliter::MakeEdges (const TopoDS_Edge& E, + const TopTools_ListOfShape& VOnE, + TopTools_ListOfShape& NE ) const +{ + TopoDS_Edge WE = E; + WE.Orientation(TopAbs_FORWARD); + + Standard_Real U1,U2, f, l; + TopoDS_Vertex V1,V2,VF,VL; + + BRep_Tool::Range(WE,f,l); + TopExp::Vertices(WE,VF,VL); + + if (VOnE.Extent() < 3) { // do not rebuild not cut edge + if (( VF.IsSame( VOnE.First() ) && VL.IsSame( VOnE.Last() )) || + VL.IsSame( VOnE.First() ) && VF.IsSame( VOnE.Last() ) ) { + NE.Append( E ); + return; + } + } + + TopTools_SequenceOfShape SV; + TopTools_ListIteratorOfListOfShape itv(VOnE); + TopTools_MapOfOrientedShape VM( VOnE.Extent() ); + for (; itv.More(); itv.Next()) + if ( VM.Add( itv.Value() )) + SV.Append(itv.Value()); + + Tri( WE, SV, myInter3d ); + + if (SV.Length() < 3) { // do not rebuild not cut edge + if (( VF.IsSame( SV.First() ) && VL.IsSame( SV.Last() )) || + VL.IsSame( SV.First() ) && VF.IsSame( SV.Last() ) ) { + NE.Append( E ); + return; + } + } + + Standard_Integer iVer, NbVer = SV.Length(); + + + //---------------------------------------------------------------- + // Construction of the new edges . + //---------------------------------------------------------------- + + if (VF.IsSame(VL)) { // closed edge + if (NbVer==1) + SV.Append( SV.First() ); + else if (!SV.First().IsSame(SV.Last())) { + Standard_Boolean isFirst=0; + Standard_Real minDU = 1.e10; + TopoDS_Vertex endV = Partition_Inter2d::FindEndVertex(VOnE, f,l, E, isFirst,minDU); + if (endV.IsSame(SV.First())) + SV.Append(endV); + else if (endV.IsSame(SV.Last())) + SV.Prepend(endV); + else + MESSAGE ("END VERTEX IS IN SEQUNCE MIDDLE"); + } + NbVer = SV.Length(); + } + + for (iVer=1; iVer < NbVer; iVer++) { + V1 = TopoDS::Vertex(SV(iVer)); + V2 = TopoDS::Vertex(SV(iVer+1)); + + TopoDS_Shape NewEdge = WE.EmptyCopied(); + V1.Orientation(TopAbs_FORWARD); + myBuilder.Add (NewEdge,V1); + V2.Orientation(TopAbs_REVERSED); + myBuilder.Add (NewEdge,V2); + + if (iVer==1) + U1 = f; + else { + V1.Orientation(TopAbs_INTERNAL); + U1=BRep_Tool::Parameter(V1,WE); + } + if (iVer+1 == NbVer) + U2 = l; + else { + V2.Orientation(TopAbs_INTERNAL); + U2=BRep_Tool::Parameter(V2,WE); + } + if (Abs(U1-U2) <= Precision::PConfusion()) { + MESSAGE( "MakeEdges(), EQUAL PARAMETERS OF DIFFERENT VERTICES"); + continue; + } + TopoDS_Edge EE=TopoDS::Edge(NewEdge); + myBuilder.Range (EE,U1,U2); + + TopoDS_Edge NEdge = TopoDS::Edge(NewEdge); + myBuilder.SameParameter(NEdge,Standard_False); + + Standard_Real tol = 1.0e-2; + Standard_Boolean flag = BRep_Tool::SameParameter(NEdge); + if (!flag) { + BRepLib::SameParameter(NEdge,tol); + } + NE.Append(NEdge.Oriented(E.Orientation())); + } +} + //======================================================================= //function : MergeEqualEdges //purpose : find equal edges, choose ones to keep and make @@ -1388,6 +1544,7 @@ void Partition_Spliter::MergeEqualEdges (const TopTools_ListOfShape& LSE) for ( ; itM.More(); itM.Next()) { EEL = itM.Value(); EEL.Append( itM.Key() ); + // choose an edge to keep, section edges have priority TopoDS_Edge EKeep; TopTools_ListIteratorOfListOfShape itEE (EEL); @@ -1398,22 +1555,30 @@ void Partition_Spliter::MergeEqualEdges (const TopTools_ListOfShape& LSE) break; } + // update edge images and build pcurves Standard_Real f,l, tol; for (itEE.Initialize (EEL); itEE.More(); itEE.Next()) { const TopoDS_Edge& E = TopoDS::Edge( itEE.Value() ); if ( E.IsSame( EKeep )) continue; + + // 1. build pcurves of the kept edge on faces where replaced edges exist const TopoDS_Edge& EReplOrig = TopoDS::Edge( myImagesEdges.Root( E )); TopTools_ListOfShape FL; - if (myInter3d.IsSectionEdge( EReplOrig )) - FL = myInter3d.SectionEdgeFaces ( EReplOrig ); - else - FL = myAsDes->Ascendant( EReplOrig ); - + FL = myAsDes->Ascendant( EReplOrig ); + Standard_Integer iFace, iFirstSectionFace = FL.Extent() + 1; + // add faces where the replaced edge is a section edge + if (myInter3d.IsSectionEdge( EReplOrig )) { + TopTools_ListIteratorOfListOfShape seIt; + seIt.Initialize( myInter3d.SectionEdgeFaces ( EReplOrig )); + for ( ; seIt.More(); seIt.Next()) + FL.Append( seIt.Value() ); + } + // loop on faces TopTools_ListIteratorOfListOfShape itF (FL); - for ( ; itF.More(); itF.Next()) { + for ( iFace = 1 ; itF.More(); itF.Next(), ++iFace ) { const TopoDS_Face& F = TopoDS::Face( itF.Value()); - // build pcurves + Handle(Geom2d_Curve) pc = BRep_Tool::CurveOnSurface( EKeep, F, f,l); if (pc.IsNull()) { Handle(Geom_Curve) C3d = BRep_Tool::Curve( EKeep, f, l); @@ -1424,12 +1589,56 @@ void Partition_Spliter::MergeEqualEdges (const TopTools_ListOfShape& LSE) } myBuilder.UpdateEdge( EKeep, pc, F, tol); } - } - // replace edges in faces - if (!myImagesEdges.HasImage( E )) - myImagesEdges.Bind( E, EKeep ); - } - } + + if (iFace >= iFirstSectionFace || + !BRep_Tool::IsClosed( EReplOrig, F )) + continue; + + // build the second pcurve for a seam + TopoDS_Vertex V = TopExp::FirstVertex( EKeep ); + Standard_Real Ukeep = BRep_Tool::Parameter( V, EKeep ); + Standard_Real Urepl = BRep_Tool::Parameter( V, E ); + + TopoDS_Edge EReplRev = E; + EReplRev.Reverse(); + Handle(Geom2d_Curve) pcRepl1 = BRep_Tool::CurveOnSurface( E, F, f,l); + Handle(Geom2d_Curve) pcRepl2 = BRep_Tool::CurveOnSurface( EReplRev, F, f,l); + + gp_Pnt2d p1r, p2r, pk; + p1r = pcRepl1->Value( Urepl ); + p2r = pcRepl2->Value( Urepl ); + pk = pc->Value( Ukeep ); + + // suppose that pk is equal to either p1r or p2r + Standard_Boolean isUPeriod = + ( Abs( p1r.X() - p2r.X() ) > Abs( p1r.Y() - p2r.Y() )); + Standard_Boolean is1Equal; + if (isUPeriod) + is1Equal = ( Abs( p1r.X() - pk.X() ) < Abs( p2r.X() - pk.X() )); + else + is1Equal = ( Abs( p1r.Y() - pk.Y() ) < Abs( p2r.Y() - pk.Y() )); + + Handle(Geom2d_Curve) pc2 = Handle(Geom2d_Curve)::DownCast + ( pc->Translated( pk, is1Equal ? p2r : p1r ) ); + + if (E.Orientation() == TopAbs_REVERSED) + is1Equal = !is1Equal; + + if (is1Equal) + myBuilder.UpdateEdge( EKeep, pc, pc2, F, tol); + else + myBuilder.UpdateEdge( EKeep, pc2, pc, F, tol); + + } // loop on a Faces where a replaced edge exists + + + // 2. update edge images according to replacement + if (myImagesEdges.HasImage( E )) + myImagesEdges.Remove( E ); + myImagesEdges.Bind( E, EKeep ); + + } // loop on a list of equal edges EEL + } // loop on a map of equal edges EEM } //======================================================================= @@ -1454,24 +1663,46 @@ void Partition_Spliter::KeepShapesInside (const TopoDS_Shape& S) // build map of internal faces TopTools_IndexedMapOfShape MIF; - - // if S is not a tool, make sure that split faces of S are in MIF - if (!isTool) - TopExp::MapShapes( myImageShape.Image(S).First(), TopAbs_FACE, MIF); - - TopoDS_Shape InsFacesComp = FindFacesInside( S, Standard_False, Standard_True); - TopExp::MapShapes( InsFacesComp, TopAbs_FACE, MIF ); - + TopoDS_Shape IntFacesComp = FindFacesInside( S, Standard_False, Standard_True); + TopExp::MapShapes( IntFacesComp, TopAbs_FACE, MIF ); TopoDS_Compound C; myBuilder.MakeCompound(C); - // leave in the result only those shapes having a face in MIF - for (it.Initialize( myShape ); it.More(); it.Next()) { + TopAbs_ShapeEnum anInternalShapeType = TopAbs_SHAPE; + if (!MIF.IsEmpty()) + { + // leave in the result only those shapes having a face in MIF + for (it.Initialize( myShape ); it.More(); it.Next()) { + const TopoDS_Shape & aResShape = it.Value(); + TopExp_Explorer expResF( aResShape, TopAbs_FACE ); + for (; expResF.More(); expResF.Next()) { + if ( MIF.Contains( expResF.Current())) { + myBuilder.Add( C, aResShape ); + if (aResShape.ShapeType() < anInternalShapeType) + anInternalShapeType = aResShape.ShapeType(); + break; + } + } + } + } - TopExp_Explorer expResF( it.Value(), TopAbs_FACE ); - for (; expResF.More(); expResF.Next()) { - if ( MIF.Contains( expResF.Current())) { + // may be S was not split by internal faces then it is missing + // in myShape, add it + if (!isTool && + (anInternalShapeType > TopAbs_SOLID || S.ShapeType() > TopAbs_SOLID)) + { + TopTools_IndexedMapOfShape MSF; // map of split faces of S + TopExp::MapShapes( myImageShape.Image(S).First(), TopAbs_FACE, MSF); + + // find a shape having all faces in MSF + for (it.Initialize( myShape ); it.More(); it.Next()) { + TopExp_Explorer expResF( it.Value(), TopAbs_FACE ); + for (; expResF.More(); expResF.Next()) { + if (! MSF.Contains( expResF.Current())) + break; + } + if (! expResF.More()) { myBuilder.Add( C, it.Value() ); break; } @@ -1500,9 +1731,9 @@ void Partition_Spliter::RemoveShapesInside (const TopoDS_Shape& S) if (!isTool) return; } - TopoDS_Shape InsFacesComp = FindFacesInside( S, Standard_False, Standard_True); + TopoDS_Shape IntFacesComp = FindFacesInside( S, Standard_False, Standard_True); TopTools_IndexedMapOfShape MIF; // map of internal faces - TopExp::MapShapes( InsFacesComp, TopAbs_FACE, MIF); + TopExp::MapShapes( IntFacesComp, TopAbs_FACE, MIF); if (MIF.IsEmpty()) return; @@ -1637,7 +1868,11 @@ Standard_Boolean Partition_Spliter::CheckTool(const TopoDS_Shape& S) Standard_Boolean hasSectionE = myInter3d.HasSectionEdge( F ); Standard_Boolean hasNewE = myAsDes->HasDescendant( F ); if (!hasSectionE && !hasNewE) - continue; // F intersects nothing + { + // F intersects nothing + myBuilder.Add( C, F ); + continue; + } // make an image for F @@ -1683,3 +1918,228 @@ Standard_Boolean Partition_Spliter::CheckTool(const TopoDS_Shape& S) return isTool; } + +//======================================================================= +//function : IsInside +//purpose : Return True if the first vertex of S1 inside S2. +// If S1.IsNull(), check infinite point against S2. +//======================================================================= + +Standard_Boolean Partition_Spliter::IsInside (const TopoDS_Shape& theS1, + const TopoDS_Shape& theS2) +{ + BRepClass3d_SolidClassifier aClassifier( theS2 ); + + TopExp_Explorer expl( theS1, TopAbs_VERTEX ); + if (!expl.More()) + aClassifier.PerformInfinitePoint( ::RealSmall()); + else + { + const TopoDS_Vertex & aVertex = TopoDS::Vertex( expl.Current() ); + aClassifier.Perform (BRep_Tool::Pnt( aVertex ), + BRep_Tool::Tolerance( aVertex )); + } + + return ( aClassifier.State() == TopAbs_IN ); +} + +//======================================================================= +//function : GetOriginalShape +//purpose : Return the shape aShape originates from. aShape +// should be a face or more complex result shape +//======================================================================= + +TopoDS_Shape Partition_Spliter::GetOriginalShape(const TopoDS_Shape& theShape) const +{ + TopoDS_Shape anOrigShape; + + TopExp_Explorer expl( theShape, TopAbs_FACE); + if (expl.More()) + { + + TopoDS_Shape aFace = expl.Current(); + if (myImagesFaces.IsImage( aFace )) + aFace = myImagesFaces.Root( aFace ); + anOrigShape = myFaceShapeMap.Find( aFace ); + } + return anOrigShape; +} + +//======================================================================= +//function : FindToolsToReconstruct +//purpose : find and store as objects tools which interfere +// with solids or are inside solids without +// an interference +//======================================================================= + +void Partition_Spliter::FindToolsToReconstruct() +{ + if (myMapTools.IsEmpty()) + return; + + Standard_Integer nbFoundTools = 0; + + // build edge - face map in order to detect interference with section edges + TopTools_IndexedDataMapOfShapeListOfShape EFM; + TopTools_MapIteratorOfMapOfShape aMapIt; + for (aMapIt.Initialize(myMapTools); aMapIt.More(); aMapIt.Next()) + TopExp::MapShapesAndAncestors( aMapIt.Key(), TopAbs_EDGE, TopAbs_FACE, EFM); + for (aMapIt.Initialize(myMapFaces); aMapIt.More(); aMapIt.Next()) + TopExp::MapShapesAndAncestors( aMapIt.Key(), TopAbs_EDGE, TopAbs_FACE, EFM); + + TopTools_MapOfShape aCurrentSolids, aCheckedShapes; + + // faces cut by new edges + TopTools_MapOfShape & aSectionFaces = myInter3d.TouchedFaces(); + + // keep solids interfering with each other in aCurrentSolids map + // and add tool faces intersecting solids as object shapes + + TopTools_ListIteratorOfListOfShape itS, itF, itCF, itE; + for (itS.Initialize( myListShapes ); itS.More(); itS.Next()) { + TopExp_Explorer expSo (itS.Value(), TopAbs_SOLID); + for (; expSo.More(); expSo.Next()) { + + // check if a solid has been already processed + const TopoDS_Shape & aSo = expSo.Current(); + if (!aCheckedShapes.Add( aSo )) + continue; + aCurrentSolids.Add( aSo ); + + // faces to check + TopTools_ListOfShape aFacesToCheck; + TopExp_Explorer exp( aSo, TopAbs_FACE ); + for ( ; exp.More(); exp.Next()) + aFacesToCheck.Append ( exp.Current()); + + // add other shapes interefering with a solid. + // iterate faces to check while appending new ones + for (itCF.Initialize (aFacesToCheck) ; itCF.More(); itCF.Next()) + { + const TopoDS_Shape& aCheckFace = itCF.Value(); +// if (!aCheckedShapes.Add( aCheckFace )) +// continue; + + // find faces interfering with aCheckFace + TopTools_ListOfShape anIntFaces; + + // ** 1. faces intersecting aCheckFace with creation of new edges on it + if ( myAsDes->HasDescendant( aCheckFace )) + { + // new edges on aCheckFace + const TopTools_ListOfShape& NEL = myAsDes->Descendant( aCheckFace ); + for (itE.Initialize( NEL); itE.More(); itE.Next()) + { + const TopoDS_Shape & aNewEdge = itE.Value(); + if (!aCheckedShapes.Add( aNewEdge )) + continue; + + // faces interfering by aNewEdge + itF.Initialize (myAsDes->Ascendant( aNewEdge )); + for (; itF.More(); itF.Next()) + if (aCheckFace != itF.Value()) + anIntFaces.Append( itF.Value() ); + + // ** 2. faces having section edge aNewEdge on aFacesToCheck + if (EFM.Contains( aNewEdge)) + { + itF.Initialize ( EFM.FindFromKey (itE.Value())); + for (; itF.More(); itF.Next()) + if (aCheckFace != itF.Value()) + anIntFaces.Append( itF.Value() ); + } + } + } + + // ** 3. faces cut by edges of aCheckFace + TopExp_Explorer expE (aCheckFace, TopAbs_EDGE); + for ( ; expE.More(); expE.Next()) + { + const TopoDS_Shape & aCheckEdge = expE.Current(); + if (aCheckedShapes.Add( aCheckEdge ) && + myInter3d.IsSectionEdge( TopoDS::Edge( aCheckEdge ))) + { + itF.Initialize( myInter3d.SectionEdgeFaces( TopoDS::Edge( aCheckEdge ))); + for (; itF.More(); itF.Next()) + if (aCheckFace != itF.Value()) + anIntFaces.Append( itF.Value() ); + } + } + + // process faces interfering with aCheckFace and shapes they + // belong to + for (itF.Initialize (anIntFaces); itF.More(); itF.Next()) + { + const TopoDS_Shape & F = itF.Value(); + if (! aCheckedShapes.Add( F )) + continue; + + Standard_Boolean isTool = myMapTools.Contains( F ); + if (isTool && + myFaceShapeMap( aCheckFace ).ShapeType() == TopAbs_SOLID ) + { + // a tool interfering with a solid + if (aSectionFaces.Contains( F )) + AddShape( F ); + ++ nbFoundTools; + if (nbFoundTools == myMapTools.Extent()) + return; + } + + const TopoDS_Shape & S = myFaceShapeMap( F ); + if (aCheckedShapes.Add( S )) + { + // a new shape interefering with aCurrentSolids is found + if (!isTool && S.ShapeType() == TopAbs_SOLID) + aCurrentSolids.Add ( S ); + // add faces to aFacesToCheck list + for ( exp.Init( S, TopAbs_FACE ); exp.More(); exp.Next()) + aFacesToCheck.Append ( exp.Current() ); + } + } + } // loop on aFacesToCheck + + // Here aCurrentSolids contains all solids interfering with each other. + // aCheckedShapes contains all faces belonging to shapes included + // in or interfering with aCurrentSolids or previously checked solids. + // Test if tool faces that do not interefere with other shapes are + // wrapped by any of aCurrentSolids + + TopTools_MapIteratorOfMapOfShape aSolidIt (aCurrentSolids); + for ( ; aSolidIt.More(); aSolidIt.Next()) + { + const TopoDS_Shape & aSolid = aSolidIt.Key(); + TopTools_MapOfShape aCheckedTools( myMapTools.Extent() ); + + TopTools_MapIteratorOfMapOfShape aToolIt (myMapTools); + for ( ; aToolIt.More(); aToolIt.Next()) + { + const TopoDS_Shape & aToolFace = aToolIt.Key(); + if (aCheckedShapes.Contains( aToolFace ) || // already found + aCheckedTools.Contains( aToolFace )) // checked against aSolid + continue; + + const TopoDS_Shape & aToolShape = myFaceShapeMap( aToolFace ); + TopExp_Explorer aToolFaceIt( aToolShape, TopAbs_FACE ); + + Standard_Boolean isInside = IsInside( aToolShape, aSolid ); + for ( ; aToolFaceIt.More(); aToolFaceIt.Next() ) + { + const TopoDS_Shape & aTool = aToolFaceIt.Current(); + aCheckedTools.Add( aTool ); + if (isInside) + { + if (aSectionFaces.Contains( aTool )) + AddShape( aTool ); + ++ nbFoundTools; + if (nbFoundTools == myMapTools.Extent()) + return; + aCheckedShapes.Add( aTool ); + } + } + } + } + + } // loop on solid shapes + } +} diff --git a/src/PARTITION/Partition_Spliter.hxx b/src/PARTITION/Partition_Spliter.hxx index bb26915c1..61700cecb 100644 --- a/src/PARTITION/Partition_Spliter.hxx +++ b/src/PARTITION/Partition_Spliter.hxx @@ -1,30 +1,12 @@ // GEOM PARTITION : partition algorithm // -// Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// Copyright (C) 2003 CEA/DEN, EDF R&D // // // // File : Partition_Spliter.hxx // Module : GEOM - #ifndef _Partition_Spliter_HeaderFile #define _Partition_Spliter_HeaderFile @@ -119,12 +101,16 @@ private: // Methods PRIVATE // +Standard_EXPORT void MakeSolids(const TopoDS_Shape& Solid,TopTools_ListOfShape& Shells) ; Standard_EXPORT void MakeShells(const TopoDS_Shape& S,TopTools_ListOfShape& NS) ; Standard_EXPORT TopoDS_Shape MakeFaces(const TopoDS_Shape& S) ; Standard_EXPORT void MakeEdges(const TopoDS_Edge& E,const TopTools_ListOfShape& VOnE,TopTools_ListOfShape& NE) const; Standard_EXPORT TopoDS_Shape FindFacesInside(const TopoDS_Shape& S,const Standard_Boolean CheckClosed = Standard_False,const Standard_Boolean All = Standard_False) ; Standard_EXPORT Standard_Boolean CheckTool(const TopoDS_Shape& S) ; Standard_EXPORT void MergeEqualEdges(const TopTools_ListOfShape& LE) ; +Standard_EXPORT static Standard_Boolean IsInside(const TopoDS_Shape& S1,const TopoDS_Shape& S2) ; +Standard_EXPORT TopoDS_Shape GetOriginalShape(const TopoDS_Shape& aShape) const; +Standard_EXPORT void FindToolsToReconstruct() ; // Fields PRIVATE @@ -135,17 +121,19 @@ BRep_Builder myBuilder; TopTools_ListOfShape myListShapes; TopTools_MapOfShape myMapFaces; TopTools_MapOfShape myMapTools; -TopTools_DataMapOfShapeShape myFaceShapeMap; +TopTools_MapOfShape myEqualEdges; TopTools_MapOfShape myNewSection; +TopTools_MapOfShape myClosedShapes; +TopTools_MapOfShape myWrappingSolid; +TopTools_DataMapOfShapeShape myFaceShapeMap; +TopTools_DataMapOfShapeShape myInternalFaces; +TopTools_DataMapOfShapeShape myIntNotClFaces; Handle_BRepAlgo_AsDes myAsDes; BRepAlgo_Image myImagesFaces; BRepAlgo_Image myImagesEdges; BRepAlgo_Image myImageShape; Partition_Inter3d myInter3d; TopTools_MapOfOrientedShape myAddedFacesMap; -TopTools_MapOfShape myEqualEdges; -TopTools_DataMapOfShapeShape myInternalFaces; -TopTools_DataMapOfShapeShape myIntNotClFaces; }; -- 2.39.2