]> SALOME platform Git repositories - modules/geom.git/commitdiff
Salome HOME
NRI : Merge BRANCH_V1_2c
authornri <nri@opencascade.com>
Tue, 4 Nov 2003 10:36:56 +0000 (10:36 +0000)
committernri <nri@opencascade.com>
Tue, 4 Nov 2003 10:36:56 +0000 (10:36 +0000)
28 files changed:
adm_local/unix/config_files/README [new file with mode: 0644]
adm_local/unix/make_commence.in
bin/VERSION
doc/html/INPUT/doxyfile
doc/html/Makefile.in
src/GEOM/GEOM_Gen_i.cc
src/GEOM/Makefile.in
src/GEOMClient/Makefile.in
src/GEOMDS/Makefile.in
src/GEOMFiltersSelection/Makefile.in
src/GEOMGUI/GeometryGUI.cxx
src/GEOMGUI/GeometryGUI_PipeDlg.cxx
src/GEOMGUI/GeometryGUI_PointDlg.cxx
src/GEOMGUI/Makefile.in
src/OBJECT/GEOM_AISShape.cxx
src/OBJECT/GEOM_Actor.cxx
src/OBJECT/Makefile.in
src/PARTITION/Makefile.in
src/PARTITION/Partition_Inter2d.cdl
src/PARTITION/Partition_Inter2d.cxx
src/PARTITION/Partition_Inter2d.hxx
src/PARTITION/Partition_Inter3d.cdl
src/PARTITION/Partition_Inter3d.cxx
src/PARTITION/Partition_Loop2d.cxx
src/PARTITION/Partition_Spliter.cdl
src/PARTITION/Partition_Spliter.cxx
src/PARTITION/Partition_Spliter.hxx
src/SKETCHER/Makefile.in

diff --git a/adm_local/unix/config_files/README b/adm_local/unix/config_files/README
new file mode 100644 (file)
index 0000000..feb997b
--- /dev/null
@@ -0,0 +1,3 @@
+This file is only here for CVS:
+CVS does not always create empty directory, and adm_local/unix/config_file
+is needed by build_configure.
index f6d5ea9cc2a4d41d62118b80436e0156807b90ae..28f29a130694de441437e98da8d22b37ec38185a 100644 (file)
@@ -47,9 +47,8 @@ PYTHONHOME = @PYTHONHOME@
 PYTHON_INCLUDES = @PYTHON_INCLUDES@
 PYTHON_LIBS = @PYTHON_LIBS@
 PYTHON_VERSION = @PYTHON_VERSION@
-PYTHON_SITE = @PYTHON_SITE@
-PYTHON_SITE_INSTALL = @PYTHON_SITE_INSTALL@
-
+PYTHON_SITE = $(prefix)/lib/python$(PYTHON_VERSION)/site-packages
+PYTHON_SITE_INSTALL = $(prefix)/lib/python$(PYTHON_VERSION)/site-packages/salome
 # QT
 
 QT_ROOT = @QT_ROOT@
@@ -101,13 +100,18 @@ MED2_MT_LIBS=@MED2_MT_LIBS@
 OCC_INCLUDES=@CAS_CPPFLAGS@
 OCC_CXXFLAGS=@CAS_CXXFLAGS@
 
-OCC_KERNEL_LIBS=@CAS_KERNEL@
-OCC_OCAF_LIBS=@CAS_OCAF@
-OCC_VIEWER_LIBS=@CAS_VIEWER@
-OCC_MODELER_LIBS=@CAS_MODELER@
-OCC_DATAEXCHANGE_LIBS=@CAS_DATAEXCHANGE@
-OCC_LIBS=@CAS_LDFLAGS@
-
+#OCC_KERNEL_LIBS=@CAS_KERNEL@
+#OCC_OCAF_LIBS=@CAS_OCAF@
+#OCC_VIEWER_LIBS=@CAS_VIEWER@
+#OCC_MODELER_LIBS=@CAS_MODELER@
+#OCC_DATAEXCHANGE_LIBS=@CAS_DATAEXCHANGE@
+#OCC_LIBS=@CAS_LDFLAGS@
+CAS_KERNEL=@CAS_KERNEL@
+CAS_OCAF=@CAS_OCAF@
+CAS_VIEWER=@CAS_VIEWER@
+CAS_MODELER=@CAS_MODELER@
+CAS_DATAEXCHANGE=@CAS_DATAEXCHANGE@
+CAS_LDPATH=@CAS_LDPATH@
 # MPICH
 
 MPICH_INCLUDES=@MPICH_INCLUDES@
@@ -164,6 +168,8 @@ CXXFLAGS+= $(CORBA_CXXFLAGS)
 #LDFLAGS+= $(CORBA_LIBS)
 LIBS+=$(CORBA_LIBS)
 
+DOXYGEN = @DOXYGEN@
+
 ## Shared libraries
 LT_STATIC_EXEC=@LT_STATIC_EXEC@
 DYNAMIC_DIRS=@DYNAMIC_DIRS@
@@ -192,8 +198,9 @@ libdir=@libdir@/salome
 # warning : if user give this path in configure we could have salome/salome :-(
 includedir=@includedir@/salome
 datadir=@datadir@/salome
-idldir=$(prefix)/idl/salome
+idldir=${prefix}/idl/salome
 sharedpydir=@libdir@/python$(PYTHON_VERSION)/site-packages/salome/shared_modules
+incmakedir=${prefix}/salome_adm/unix
 
 docdir=$(datadir)/doc
 
@@ -201,7 +208,7 @@ docdir=$(datadir)/doc
 # begin of package rules
 #
 
-.PHONY: all lib bin inc resources tests install uninstall dep depend depend_idl cleandep mostlyclean clean distclean
+.PHONY: all lib bin inc resources data doc tests install uninstall dep depend depend_idl cleandep mostlyclean clean distclean
 
 .SUFFIXES: .cxx .cc .c .f .o .lo .idl .py .i .ui .po .qm
 
index f38a71b1433638392dde66bfe868800ccbbfc191..9e100c4dc947dd003d48677ff699b150cc96d939 100755 (executable)
@@ -1 +1 @@
-THIS IS SALOME PRO - GEOM VERSION: 1.2
+THIS IS SALOME PRO - GEOM VERSION: 1.3.0
index d6fd95cccedf25c327b1388dd797076a8df8f2b3..940499479292edaf46a387604b7be40047b11cc2 100755 (executable)
@@ -3,7 +3,7 @@
 #---------------------------------------------------------------------------
 # General configuration options
 #---------------------------------------------------------------------------
-PROJECT_NAME           = "SALOME PRO - GEOM - v.1.2"
+PROJECT_NAME           = "SALOME PRO - GEOM - v.1.3.0"
 PROJECT_NUMBER         = id#1.1
 OUTPUT_DIRECTORY       = ../
 OUTPUT_LANGUAGE        = English
index d52af489287cb31c7b5f21d1c987fabd89a47dc5..d364ac76dc3c7aeccff54c1226ef9aa492d2e5dc 100644 (file)
@@ -6,6 +6,7 @@
 #
 # source path
 top_srcdir=@top_srcdir@
+root_srcdir=@ROOT_SRCDIR@
 top_builddir=../..
 srcdir=@srcdir@
 VPATH=.:@srcdir@
@@ -16,7 +17,7 @@ doxygen=@DOXYGEN@
 doc:
        cp -fr $(srcdir)/INPUT ./; \
        cd INPUT; \
-       sed 's|../../../share/salome|../$(top_srcdir)|' doxyfile > doxyfile1; \
+       sed 's|../../../share/salome|$(root_srcdir)|' doxyfile > doxyfile1; \
        mv -f doxyfile1 doxyfile; \
        $(doxygen) ./doxyfile; \
        cd ..; \
index 4bc0f4dbf3cdf82533e02a37d4e76ffb8b34bc5d..fbc67a229bd3b04bbf552ca8e8f47a52125e2820 100644 (file)
@@ -55,7 +55,11 @@ using namespace std;
 #include <GC_Root.hxx>
 
 #include <BRepCheck_Analyzer.hxx>
+#if OCC_VERSION_MAJOR >= 5
+#include <BRepAlgo.hxx>
+#else
 #include <BRepAlgoAPI.hxx>
+#endif
 #include <BRepAdaptor_Surface.hxx>
 #include <BRepBuilderAPI_Copy.hxx>
 #include <BRepAlgoAPI_Common.hxx>
@@ -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);
     }
   }
@@ -4389,7 +4406,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 {
index 800efcb6eade5cd595a70d29047cac0de09db3ce..738e9ae649be5aeff5dde623fb0e5af10c45715c 100644 (file)
@@ -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 =
index aed4bccb67777f413ead541c7bd0c0594f1934da..32db3e2204940c449419088c49c1ae96226814c1 100644 (file)
@@ -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@
index 27834c28b2d6f881a5023ac8f9e5c4b2c98e4615..b58244fd16a30ce0422087f89bc6bc8687e1dd91 100644 (file)
@@ -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 =
index 0a4ac65f62ffc6f161b264d38c920bab68a15b2f..851695357d739835a58712d1d6c5671f561f06a2 100644 (file)
@@ -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 =
index 0aa9b4ffc96f9d7f73eb8fb9fae71462ff1b7946..080d48b0a08c8fdc647e57e0ea66cc9417e1218b 100644 (file)
@@ -717,9 +717,9 @@ GEOM_Actor* GeometryGUI::ConvertIORinGEOMActor( const char * IOR,
 GEOM::GEOM_Shape_ptr GeometryGUI::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 = GeomGUI->myActiveStudy->getStudyDocument();
@@ -727,23 +727,23 @@ GEOM::GEOM_Shape_ptr GeometryGUI::ConvertIOinGEOMShape( const Handle(SALOME_Inte
     SALOMEDS::GenericAttribute_var anAttr;
     SALOMEDS::AttributeIOR_var     anIOR;
     if ( !obj->_is_nil() ) {
-       if (obj->FindAttribute(anAttr, "AttributeIOR")) {
-         anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
-        aShape = myComponentGeom->GetIORFromString(anIOR->Value()) ;
-        testResult = true ;
-        return aShape;
-       }
+      if (obj->FindAttribute(anAttr, "AttributeIOR")) {
+       anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
+       aShape = myComponentGeom->GetIORFromString(anIOR->Value()) ;
+       if(!CORBA::is_nil(aShape)) testResult = true ;
+       return aShape._retn();
+      }
     }
   }
   /* case Graphical Object */
   if ( IO->IsInstance(STANDARD_TYPE(GEOM_InteractiveObject)) ) {
     Handle(GEOM_InteractiveObject) GIObject = Handle(GEOM_InteractiveObject)::DownCast( IO );
     Standard_CString ior = GIObject->getIOR();
-    testResult = true ;
     aShape = myComponentGeom->GetIORFromString(ior) ;
-    return aShape;
-  } 
-  return aShape ;
+    if(!CORBA::is_nil(aShape)) testResult = true ;
+    return aShape._retn();
+  }
+  return aShape._retn();
 }
 
 
index 0e45fb8a8e48de50552a2af52ed3d0bbae6ca081..7746c59857bffb2feffa4bad9d7825514414242d 100644 (file)
@@ -50,7 +50,11 @@ using namespace std;
 #include <Standard_ErrorHandler.hxx> 
 #include <Standard_Failure.hxx>
 #include <BRepOffsetAPI_MakePipe.hxx> 
+#if OCC_VERSION_MAJOR >= 5
+#include <BRepAlgo.hxx>
+#else
 #include <BRepAlgoAPI.hxx>
+#endif
 
 
 //=================================================================================
@@ -386,7 +390,11 @@ void GeometryGUI_PipeDlg::SelectionIntoArgument()
        try 
        {
                tds = BRepOffsetAPI_MakePipe(aWire,myShape1 ) ;
+#if OCC_VERSION_MAJOR >= 5
+               if (  BRepAlgo::IsValid(tds) ) 
+#else
                if (  BRepAlgoAPI::IsValid(tds) ) 
+#endif
                {
                        //Draw Pipe
                        mySimulationTopoDs = tds;
index 2423b809f1f18e1d671db8226f0db63419d1feb5..017a00043de8b51e7643553a051f8af2a562e28d 100644 (file)
@@ -40,7 +40,11 @@ using namespace std;
 
 #include <BRepBuilderAPI_MakeVertex.hxx>
 #include <BRep_Tool.hxx>
+#if OCC_VERSION_MAJOR >= 5
+#include <BRepAlgo.hxx>
+#else
 #include <BRepAlgoAPI.hxx>
+#endif
 #include <Geom_Curve.hxx>
 
 #include <qbuttongroup.h>
@@ -763,7 +767,11 @@ void GeometryGUI_PointDlg::ActivateThisDialog( )
 //=================================================================================
 bool GeometryGUI_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 ;
index be0a495ef74b98b3224015054611546e4b7a6851..568b62a57e9d607bd2397b75401532ad6d414997 100644 (file)
@@ -171,6 +171,7 @@ LIB_SERVER_IDL =
 CPPFLAGS += $(QT_INCLUDES) $(VTK_INCLUDES) $(OGL_INCLUDES) $(OCC_INCLUDES) $(PYTHON_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome
 CXXFLAGS += $(OCC_CXXFLAGS) -I${KERNEL_ROOT_DIR}/include/salome
 
-LDFLAGS += -lOCCViewer -lVTKViewer -lSalomeObject -lSalomeGUI -lGEOMClient -lGEOMObject -lGEOMFiltersSelection -lGEOMSketcher $(OCC_KERNEL_LIBS) $(OCC_MODELER_LIBS) -L${KERNEL_ROOT_DIR}/lib/salome
+LDFLAGS += -lOCCViewer -lVTKViewer -lSalomeObject -lSalomeGUI -lGEOMClient -lGEOMObject -lGEOMFiltersSelection -lGEOMSketcher $(CAS_LDPATH) -lTKFillet -lTKOffset -L${KERNEL_ROOT_DIR}/lib/salome
+
 
 @CONCLUDE@
index 93cbeaa7873882c58fc8f2886ed9af797f8f06a5..e87917f5e173baaa1d09f251ee253a3d050a5516 100644 (file)
@@ -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);
index e29c665cbd465c69308d824bf5810aa1d031f2ff..0602bc5caa36c4c2a42156b062364548e1f7a4da 100644 (file)
@@ -274,7 +274,8 @@ void GEOM_Actor::Render(vtkRenderer *ren, vtkMapper *Mapper)
     aMatrix->Delete();    
   } else
     this->Device->Render(ren, this->Mapper);
-  this->EstimatedRenderTime = WireframeMapper->GetTimeToDraw();
+ if(WireframeMapper!=NULL) this->EstimatedRenderTime = WireframeMapper->GetTimeToDraw(); 
+ else if(ShadingMapper!=NULL) this->EstimatedRenderTime = ShadingMapper->GetTimeToDraw();
 }
 
 // SubShape
index c3978f5ed914dfd24562dbddda1ddf4b5d6739d2..154c41d95bc9b2a07495c95bba5dd54dc0b0e504 100644 (file)
@@ -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 $@
 
index a7a9fa34bf01caa7a8d1bef40e7cfc3fa2cf017e..76de606eb4b0a07359a073c1820110ff2166bb94 100644 (file)
@@ -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 $@
index a3a4d15d2052435bf1535bfdae100fed2ecdda96..1dcaa264bd7879eba680fd4f41af6cf0462a7798 100644 (file)
@@ -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;
 
index e15bf24e3b6a73e4979080dd8743800860eceeba..54b25e6e99198d4ba6b7a3d5e80d8a589295b2aa 100644 (file)
@@ -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 <TopExp.hxx>
-#include <TopExp_Explorer.hxx>
-
+#include <BRepAdaptor_Curve.hxx>
 #include <BRepAlgo_AsDes.hxx>
-
+#include <BRepLib_MakeVertex.hxx>
 #include <BRep_Builder.hxx>
 #include <BRep_Tool.hxx>
-#include <BRepLib_MakeVertex.hxx>
-#include <BRepAdaptor_Curve.hxx>
-
-#include <gp_Pnt.hxx>
-#include <TopoDS.hxx>
-#include <TopoDS_Edge.hxx>
-#include <TopoDS_Vertex.hxx>
+#include <Geom_Surface.hxx>
+#include <Precision.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopOpeBRepDS_Transition.hxx>
 #include <TopOpeBRep_EdgesIntersector.hxx>
 #include <TopOpeBRep_Point2d.hxx>
-#include <TopOpeBRepDS_Transition.hxx>
-#include <TopTools_ListOfShape.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
-#include <TopTools_MapOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
 #include <TopTools_MapIteratorOfMapOfShape.hxx>
-
-#include <stdio.h>
-#include <Precision.hxx>
+#include <TopTools_MapOfShape.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <gp_Pnt.hxx>
 
 #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_"<<NbE2d-2<<" E2d_"<<NbE2d-1 ); }
-#endif
-       continue;
-      }
+      if (sqd1 > 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;
+}
index 7d82aa34bf5797a4800a7f880f0f52b5808fcd64..059be96135a572f8b9258e1221d50e4e73856110 100644 (file)
@@ -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) ;
 
 
 
index 38c504aeecd4e4fc1544615d0cf0856bfce393b2..44be26eaf61842557db6ee2290dcbe470c5a033b 100644 (file)
@@ -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
index dc7e4606c8bb5a094b629a3bdfe65aa1292c8fc0..7724b73f1a2a76103622ccc3030f36e346fbaa17 100644 (file)
 //  $Header$
 
 using namespace std;
-#include "Partition_Inter3d.ixx"
 #include "Partition_Inter2d.hxx"
+#include "Partition_Inter3d.ixx"
 #include "utilities.h"
 
-#include <BRepOffset_Tool.hxx>
-#include <BRep_Builder.hxx>
-#include <BRep_Tool.hxx>
 #include <BRepAlgo_AsDes.hxx>
 #include <BRepAlgo_Image.hxx>
 #include <BRepLib.hxx>
+#include <BRepOffset_Tool.hxx>
+#include <BRep_Builder.hxx>
+#include <BRep_Tool.hxx>
 
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
 
+#include <TopOpeBRepTool_BoxSort.hxx>
+#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
 #include <TopoDS.hxx>
-#include <TopoDS_Vertex.hxx>
+#include <TopoDS_Compound.hxx>
 #include <TopoDS_Edge.hxx>
 #include <TopoDS_Face.hxx>
-#include <TopoDS_Compound.hxx>
-#include <TopTools_ListOfShape.hxx>
-#include <TopTools_ListIteratorOfListOfShape.hxx>
-#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
-#include <TopOpeBRepTool_BoxSort.hxx>
+#include <TopoDS_Vertex.hxx>
 
 #ifdef DEB
 #include <DBRep.hxx>
 #endif
 
-#include <stdio.h>
-#include <TopOpeBRepDS_HDataStructure.hxx>
-#include <TopOpeBRep_DSFiller.hxx>
-#include <TopOpeBRepTool_GeomTool.hxx>
-#include <TopOpeBRepTool_OutCurveType.hxx>
-#include <TopOpeBRepDS_BuildTool.hxx>
+#include <BRepLib_MakeVertex.hxx>
+#include <BRepTools.hxx>
+#include <Extrema_ExtPS.hxx>
+#include <Extrema_POnSurf.hxx>
+#include <Geom2dAPI_ProjectPointOnCurve.hxx>
+#include <Geom2d_Curve.hxx>
+#include <GeomAPI_ProjectPointOnCurve.hxx>
+#include <GeomAdaptor_Surface.hxx>
+#include <Geom_Curve.hxx>
+#include <Geom_RectangularTrimmedSurface.hxx>
+#include <Geom_SphericalSurface.hxx>
+#include <Geom_Surface.hxx>
+#include <Geom_ToroidalSurface.hxx>
+#include <Geom_TrimmedCurve.hxx>
+#include <Precision.hxx>
+#include <TColStd_MapOfInteger.hxx>
 #include <TopOpeBRepBuild_Builder.hxx>
+#include <TopOpeBRepDS_BuildTool.hxx>
 #include <TopOpeBRepDS_CurveExplorer.hxx>
-#include <Geom2d_Curve.hxx>
+#include <TopOpeBRepDS_HDataStructure.hxx>
+#include <TopOpeBRepDS_Interference.hxx>
 #include <TopOpeBRepDS_PointIterator.hxx>
 #include <TopOpeBRepDS_Transition.hxx>
-#include <Geom_Curve.hxx>
 #include <TopOpeBRepTool_CurveTool.hxx>
-#include <TopOpeBRepDS_Interference.hxx>
+#include <TopOpeBRepTool_GeomTool.hxx>
+#include <TopOpeBRepTool_OutCurveType.hxx>
+#include <TopOpeBRep_DSFiller.hxx>
 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
-#include <BRepLib_MakeVertex.hxx>
-#include <Precision.hxx>
-#include <TColStd_MapOfInteger.hxx>
-#include <BRepTools.hxx>
-#include <Geom_RectangularTrimmedSurface.hxx>
-#include <Geom_Surface.hxx>
-#include <Geom_TrimmedCurve.hxx>
-#include <Geom2dAPI_ProjectPointOnCurve.hxx>
-#include <GeomAPI_ProjectPointOnCurve.hxx>
+#include <stdio.h>
 
 //=======================================================================
 //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;
 }
 
 //=======================================================================
index 1e0a2578746a564093510a1d37277f68055f6ee8..9b229f97943c35920634ac15ebd518553733bfde 100644 (file)
@@ -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 <BRepAdaptor_Curve2d.hxx>
 #include <BRepAdaptor_Surface.hxx>
 #include <BRepAlgo_AsDes.hxx>
+#include <BRepAlgo_FaceRestrictor.hxx>
 #include <BRepOffset_DataMapOfShapeReal.hxx>
 #include <BRepTopAdaptor_FClass2d.hxx>
 #include <BRep_Builder.hxx>
@@ -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 <NE> connected <CE> by the vertex <CV> in the list <LE>.
-//           <NE> Is erased  of the list. If <CE> is too in the list <LE>
-//           with the same orientation, it's erased of the list
+//purpose  : Find in the list <LE> the edge <NE> connected with <CE> by
+//           the vertex <CV>.
+//           <NE> is removed from the list. If <CE> is in <LE>
+//           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 <outerEM>, 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 <BRepFeat_SplitShape.hxx>
-void  Partition_Loop2d::WiresToFaces(const BRepAlgo_Image& EdgeImage)
-#else
-     
-# include <BRepAlgo_FaceRestrictor.hxx>
 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 );
 }
index 252e94b0b57dbac17413ac262946c2b6a886deb8..0fc9b5be580c1fc624f99cf7bd3b0d76520789a5 100644 (file)
@@ -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
         --          <LE> 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;
index 502fbc956f63bd790345cb0202d93eb3ecea052b..8dd5d136dbb53aa2454203cd8ae9200ca85d83aa 100644 (file)
 //  $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 <TopExp_Explorer.hxx>
-#include <TopExp.hxx>
 #include <Precision.hxx>
 #include <TopAbs_Orientation.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
 
 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
 #include <TopTools_DataMapOfShapeListOfShape.hxx>
@@ -49,13 +49,13 @@ using namespace std;
 #include <TopTools_MapIteratorOfMapOfShape.hxx>
 #include <TopTools_SequenceOfShape.hxx>
 
-#include <gp_Pnt2d.hxx>
-#include <gp_Pnt.hxx>
-#include <gp_Vec.hxx>
 #include <Geom2d_Curve.hxx>
 #include <Geom_Curve.hxx>
 #include <Geom_Surface.hxx>
 #include <Geom_TrimmedCurve.hxx>
+#include <gp_Pnt.hxx>
+#include <gp_Pnt2d.hxx>
+#include <gp_Vec.hxx>
 
 #include <TopoDS.hxx>
 #include <TopoDS_Compound.hxx>
@@ -67,31 +67,41 @@ using namespace std;
 #include <TopoDS_Vertex.hxx>
 #include <TopoDS_Wire.hxx>
 
-#include <BRep_Tool.hxx>
-#include <BRepLib.hxx>
 #include <BRepBndLib.hxx>
+#include <BRepClass3d_SolidClassifier.hxx>
+#include <BRepLib.hxx>
+#include <BRep_Tool.hxx>
 
-#include <stdio.h>
 #include <Extrema_ExtPC.hxx>
 #include <GeomAdaptor_Curve.hxx>
 #include <TopOpeBRepTool_CurveTool.hxx>
 
 #ifdef DEB
-#define DRAW 0
+//# define PART_PERF
 #endif
 
-#ifdef DRAW
-#include <DBRep.hxx>
-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 <OSD_Chronometer.hxx>
+#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.
 //           <addSame>==True makes consider same edges as equal
 //           Put in <AllEqMap> 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
+  }
+}
index bb26915c1d63ff43639984c8c54085ecc9c9b5f0..61700cecbc2e9d328bc3586ec74cd1e3e56346be 100644 (file)
@@ -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;
 
 
 };
index eedb7f2cd0e0d1baada0cf7f52d1b9fc87771e3f..3e988eb32831aca57b2f92958018e9b542f142c6 100644 (file)
@@ -46,7 +46,7 @@ EXPORT_HEADERS= GEOM_Sketcher.h \
 # additionnal information to compil and link file
 CPPFLAGS += $(OCC_INCLUDES) $(QT_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  += $(QT_LIBS) $(CAS_LDPATH) -lTKTopAlgo -L${KERNEL_ROOT_DIR}/lib/salome
 
 # additional file to be cleaned
 MOSTLYCLEAN =