From: admin Date: Wed, 9 Jul 2003 07:30:57 +0000 (+0000) Subject: This commit was generated by cvs2git to create tag 'V1_1_1'. X-Git-Tag: V1_1_1 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=1d2d14f1dc442fb3684e03587868474343f24f0a;p=modules%2Fgeom.git This commit was generated by cvs2git to create tag 'V1_1_1'. Sprout from master 2003-06-12 10:38:56 UTC prascle 'PR: avoids unnecessary compilation after regeneration of SALOMEconfig.h, with gcc3.2' Cherrypick from IMPORT 2003-07-09 07:30:56 UTC nri 'sources v1.2': OBJECT/GEOM_AISShape.cxx OBJECT/GEOM_AISShape.hxx OBJECT/GEOM_AISShape.ixx OBJECT/GEOM_AISShape.jxx OBJECT/GEOM_Actor.cxx OBJECT/GEOM_Actor.h OBJECT/GEOM_AssemblyBuilder.cxx OBJECT/GEOM_AssemblyBuilder.h OBJECT/GEOM_InteractiveObject.cxx OBJECT/GEOM_InteractiveObject.hxx OBJECT/GEOM_InteractiveObject.ixx OBJECT/GEOM_InteractiveObject.jxx OBJECT/GEOM_OCCReader.cxx OBJECT/GEOM_OCCReader.h OBJECT/Handle_GEOM_AISShape.hxx OBJECT/Handle_GEOM_InteractiveObject.hxx OBJECT/Makefile.in PARTITION/Makefile.in PARTITION/Partition.cdl PARTITION/Partition_Inter2d.cdl PARTITION/Partition_Inter2d.cxx PARTITION/Partition_Inter2d.hxx PARTITION/Partition_Inter2d.ixx PARTITION/Partition_Inter2d.jxx PARTITION/Partition_Inter3d.cdl PARTITION/Partition_Inter3d.cxx PARTITION/Partition_Inter3d.hxx PARTITION/Partition_Inter3d.ixx PARTITION/Partition_Inter3d.jxx PARTITION/Partition_Loop.cdl PARTITION/Partition_Loop.cxx PARTITION/Partition_Loop.hxx PARTITION/Partition_Loop.ixx PARTITION/Partition_Loop.jxx PARTITION/Partition_Loop2d.cdl PARTITION/Partition_Loop2d.cxx PARTITION/Partition_Loop2d.hxx PARTITION/Partition_Loop2d.ixx PARTITION/Partition_Loop2d.jxx PARTITION/Partition_Loop3d.cdl PARTITION/Partition_Loop3d.cxx PARTITION/Partition_Loop3d.hxx PARTITION/Partition_Loop3d.ixx PARTITION/Partition_Loop3d.jxx PARTITION/Partition_Spliter.cdl PARTITION/Partition_Spliter.cxx PARTITION/Partition_Spliter.hxx PARTITION/Partition_Spliter.ixx PARTITION/Partition_Spliter.jxx SKETCHER/GEOM_Sketcher.cxx SKETCHER/GEOM_Sketcher.h SKETCHER/GEOM_SketcherStatus.h SKETCHER/Makefile.in --- diff --git a/OBJECT/GEOM_AISShape.cxx b/OBJECT/GEOM_AISShape.cxx new file mode 100644 index 000000000..93cbeaa78 --- /dev/null +++ b/OBJECT/GEOM_AISShape.cxx @@ -0,0 +1,147 @@ +// GEOM OBJECT : interactive object for Geometry entities visualization +// +// 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 +// +// +// +// File : GEOM_AISShape.cxx +// Author : Nicolas REJNERI +// Module : GEOM +// $Header$ + +using namespace std; +/*! + \class GEOM_AISShape GEOM_AISShape.hxx + \brief .... +*/ + +#include "GEOM_AISShape.ixx" +#include "SALOME_InteractiveObject.hxx" + +#include "utilities.h" + +// Open CASCADE Includes +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +GEOM_AISShape::GEOM_AISShape(const TopoDS_Shape& shape, + const Standard_CString aName): SALOME_AISShape(shape) +{ + myIO = NULL; + myName = new char [strlen(aName)+1]; + strcpy( myName, aName); + + myShadingColor = Quantity_Color( Quantity_NOC_GOLDENROD ); +} + +void GEOM_AISShape::setIO(const Handle(SALOME_InteractiveObject)& io){ + myIO = io; +} + +Handle(SALOME_InteractiveObject) GEOM_AISShape::getIO(){ + return myIO; +} + +Standard_Boolean GEOM_AISShape::hasIO(){ + return !( myIO == NULL ) ; +} + +void GEOM_AISShape::setName(const Standard_CString aName) +{ + myName = new char [strlen(aName)+1]; + strcpy( myName, aName); + + if ( hasIO() ) + myIO->setName(aName); +} + +Standard_CString GEOM_AISShape::getName(){ + return myName; +} + +void GEOM_AISShape::Compute(const Handle(PrsMgr_PresentationManager3d)& aPresentationManager, + const Handle(Prs3d_Presentation)& aPrs, + const Standard_Integer aMode) +{ + if (IsInfinite()) aPrs->SetInfiniteState(Standard_True); //pas de prise en compte lors du FITALL + + StdSelect_DisplayMode d = (StdSelect_DisplayMode) aMode; + + switch (d) { + case StdSelect_DM_Wireframe: + { + StdPrs_WFShape::Add(aPrs,myshape,myDrawer); + break; + } + case StdSelect_DM_Shading: + { + myDrawer->ShadingAspect()->Aspect()->SetDistinguishOn(); + myDrawer->ShadingAspect()->Aspect()->SetFrontMaterial(Graphic3d_NOM_BRASS); + 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); + myDrawer->ShadingAspect()->Aspect()->SetFrontMaterial(FMat); + myDrawer->ShadingAspect()->Aspect()->SetBackMaterial(BMat); + + //Handle(Graphic3d_AspectFillArea3d) a4bis = myDrawer->ShadingAspect()->Aspect(); + // P->SetPrimitivesAspect(a4bis); + // G->SetGroupPrimitivesAspect(a4bis); + //a4bis->SetInteriorColor(myShadingColor); + myDrawer->ShadingAspect()->SetColor(myShadingColor); + + StdPrs_ShadedShape::Add(aPrs,myshape,myDrawer); + break; + } + } + // aPrs->ReCompute(); // for hidden line recomputation if necessary... +} + +void GEOM_AISShape::SetTransparency(const Standard_Real aValue) +{ + if(aValue<0.0 || aValue>1.0) return; + + if(aValue<=0.05) + { + UnsetTransparency(); + return; + } + + Graphic3d_MaterialAspect FMat = myDrawer->ShadingAspect()->Aspect()->FrontMaterial(); + Graphic3d_MaterialAspect BMat = myDrawer->ShadingAspect()->Aspect()->BackMaterial(); + FMat.SetTransparency(aValue); BMat.SetTransparency(aValue); + myDrawer->ShadingAspect()->Aspect()->SetFrontMaterial(FMat); + myDrawer->ShadingAspect()->Aspect()->SetBackMaterial(BMat); + myTransparency = aValue; +} + +void GEOM_AISShape::SetShadingColor(const Quantity_Color &aCol) +{ + myShadingColor = aCol; +} diff --git a/OBJECT/GEOM_AISShape.hxx b/OBJECT/GEOM_AISShape.hxx new file mode 100644 index 000000000..d809c0dbb --- /dev/null +++ b/OBJECT/GEOM_AISShape.hxx @@ -0,0 +1,136 @@ +// GEOM OBJECT : interactive object for Geometry entities visualization +// +// 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 +// +// +// +// File : GEOM_AISShape.hxx +// Module : GEOM + +#ifndef _GEOM_AISShape_HeaderFile +#define _GEOM_AISShape_HeaderFile + +#ifndef _Standard_HeaderFile +#include +#endif +#ifndef _Handle_GEOM_AISShape_HeaderFile +#include "Handle_GEOM_AISShape.hxx" +#endif + +#ifndef _Handle_SALOME_InteractiveObject_HeaderFile +#include "Handle_SALOME_InteractiveObject.hxx" +#endif +#ifndef _Standard_CString_HeaderFile +#include +#endif +#ifndef _SALOME_AISShape_HeaderFile +#include "SALOME_AISShape.hxx" +#endif +#ifndef _Standard_Boolean_HeaderFile +#include +#endif +#ifndef _Handle_PrsMgr_PresentationManager3d_HeaderFile +#include +#endif +#ifndef _Handle_Prs3d_Presentation_HeaderFile +#include +#endif + +class PrsMgr_PresentationManager3d; +class Prs3d_Presentation; +class SALOME_InteractiveObject; +class TopoDS_Shape; + + +class GEOM_AISShape : public SALOME_AISShape { + +public: + + inline void* operator new(size_t,void* anAddress) + { + return anAddress; + } + inline void* operator new(size_t size) + { + return Standard::Allocate(size); + } + inline void operator delete(void *anAddress) + { + if (anAddress) Standard::Free((Standard_Address&)anAddress); + } +// inline void operator delete(void *anAddress, size_t size) +// { +// if (anAddress) Standard::Free((Standard_Address&)anAddress,size); +// } + // Methods PUBLIC + // +Standard_EXPORT GEOM_AISShape(const TopoDS_Shape& shape, const Standard_CString aName); +Standard_EXPORT Standard_Boolean hasIO() ; +Standard_EXPORT void setIO(const Handle(SALOME_InteractiveObject)& name) ; +Standard_EXPORT void setName(const Standard_CString aName) ; +Standard_EXPORT Standard_CString getName() ; +Standard_EXPORT Handle_SALOME_InteractiveObject getIO() ; +Standard_EXPORT ~GEOM_AISShape(); + +Standard_EXPORT void SetTransparency(const Standard_Real aValue); +Standard_EXPORT void SetShadingColor(const Quantity_Color &aCol); + +Standard_EXPORT virtual void Compute(const Handle(PrsMgr_PresentationManager3d)& aPresentationManager, + const Handle(Prs3d_Presentation)& aPresentation, + const Standard_Integer aMode = 0) ; + + // Type management + // + Standard_EXPORT friend Handle_Standard_Type& GEOM_AISShape_Type_(); + Standard_EXPORT const Handle(Standard_Type)& DynamicType() const; + Standard_EXPORT Standard_Boolean IsKind(const Handle(Standard_Type)&) const; + +protected: + + // Methods PROTECTED + // + + + // Fields PROTECTED + // + + +private: + + // Methods PRIVATE + // + + + // Fields PRIVATE + // + Handle_SALOME_InteractiveObject myIO; + Standard_CString myName; + Quantity_Color myShadingColor; +}; + + + + + +// other inline functions and methods (like "C++: function call" methods) +// + + +#endif diff --git a/OBJECT/GEOM_AISShape.ixx b/OBJECT/GEOM_AISShape.ixx new file mode 100644 index 000000000..7baed81b7 --- /dev/null +++ b/OBJECT/GEOM_AISShape.ixx @@ -0,0 +1,91 @@ +// GEOM OBJECT : interactive object for Geometry entities visualization +// +// 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 +// +// +// +// File : GEOM_AISShape.ixx +// Module : GEOM + +#include "GEOM_AISShape.jxx" + +#ifndef _Standard_TypeMismatch_HeaderFile +#include +#endif + +GEOM_AISShape::~GEOM_AISShape() {} + + + +Standard_EXPORT Handle_Standard_Type& GEOM_AISShape_Type_() +{ + + static Handle_Standard_Type aType1 = STANDARD_TYPE(SALOME_AISShape); + if ( aType1.IsNull()) aType1 = STANDARD_TYPE(SALOME_AISShape); + static Handle_Standard_Type aType2 = STANDARD_TYPE(AIS_Shape); + if ( aType2.IsNull()) aType2 = STANDARD_TYPE(AIS_Shape); + static Handle_Standard_Type aType3 = STANDARD_TYPE(AIS_InteractiveObject); + if ( aType3.IsNull()) aType3 = STANDARD_TYPE(AIS_InteractiveObject); + static Handle_Standard_Type aType4 = STANDARD_TYPE(SelectMgr_SelectableObject); + if ( aType4.IsNull()) aType4 = STANDARD_TYPE(SelectMgr_SelectableObject); + static Handle_Standard_Type aType5 = STANDARD_TYPE(PrsMgr_PresentableObject); + if ( aType5.IsNull()) aType5 = STANDARD_TYPE(PrsMgr_PresentableObject); + static Handle_Standard_Type aType6 = STANDARD_TYPE(MMgt_TShared); + if ( aType6.IsNull()) aType6 = STANDARD_TYPE(MMgt_TShared); + static Handle_Standard_Type aType7 = STANDARD_TYPE(Standard_Transient); + if ( aType7.IsNull()) aType7 = STANDARD_TYPE(Standard_Transient); + + + static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,aType4,aType5,aType6,aType7,NULL}; + static Handle_Standard_Type _aType = new Standard_Type("GEOM_AISShape", + sizeof(GEOM_AISShape), + 1, + (Standard_Address)_Ancestors, + (Standard_Address)NULL); + + return _aType; +} + + +// DownCast method +// allow safe downcasting +// +const Handle(GEOM_AISShape) Handle(GEOM_AISShape)::DownCast(const Handle(Standard_Transient)& AnObject) +{ + Handle(GEOM_AISShape) _anOtherObject; + + if (!AnObject.IsNull()) { + if (AnObject->IsKind(STANDARD_TYPE(GEOM_AISShape))) { + _anOtherObject = Handle(GEOM_AISShape)((Handle(GEOM_AISShape)&)AnObject); + } + } + + return _anOtherObject ; +} +const Handle(Standard_Type)& GEOM_AISShape::DynamicType() const +{ + return STANDARD_TYPE(GEOM_AISShape) ; +} +Standard_Boolean GEOM_AISShape::IsKind(const Handle(Standard_Type)& AType) const +{ + return (STANDARD_TYPE(GEOM_AISShape) == AType || SALOME_AISShape::IsKind(AType)); +} +Handle_GEOM_AISShape::~Handle_GEOM_AISShape() {} + diff --git a/OBJECT/GEOM_AISShape.jxx b/OBJECT/GEOM_AISShape.jxx new file mode 100644 index 000000000..8f66299fd --- /dev/null +++ b/OBJECT/GEOM_AISShape.jxx @@ -0,0 +1,41 @@ +// GEOM OBJECT : interactive object for Geometry entities visualization +// +// 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 +// +// +// +// File : GEOM_AISShape.jxx +// Module : GEOM + +#ifndef _GEOM_InteractiveObject_HeaderFile +#include "GEOM_InteractiveObject.hxx" +#endif +#ifndef _TopoDS_Shape_HeaderFile +#include +#endif +#ifndef _GEOM_AISShape_HeaderFile +#include "GEOM_AISShape.hxx" +#endif +#ifndef _PrsMgr_PresentationManager3d_HeaderFile +#include +#endif +#ifndef _Prs3d_Presentation_HeaderFile +#include +#endif \ No newline at end of file diff --git a/OBJECT/GEOM_Actor.cxx b/OBJECT/GEOM_Actor.cxx new file mode 100644 index 000000000..e29c665cb --- /dev/null +++ b/OBJECT/GEOM_Actor.cxx @@ -0,0 +1,464 @@ +// GEOM OBJECT : interactive object for Geometry entities visualization +// +// 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 +// +// +// +// File : GEOM_Actor.cxx +// Author : Christophe ATTANASIO +// Module : GEOM +// $Header$ + +using namespace std; +/*! + \class GEOM_Actor GEOM_Actor.h + \brief This class allows to display an OpenCASCADE CAD model in a VTK viewer. +*/ + +#include "GEOM_Actor.h" + +// OpenCASCADE Includes +#include "GEOM_OCCReader.h" +#include + +//------------------------------------------------------------- +// Main methods +//------------------------------------------------------------- + + +GEOM_Actor* GEOM_Actor::New() +{ + // First try to create the object from the vtkObjectFactory + vtkObject* ret = vtkObjectFactory::CreateInstance("GEOM_Actor"); + if(ret) + { + return (GEOM_Actor*)ret; + } + // If the factory was unable to create the object, then create it here. + return new GEOM_Actor; +} + + +GEOM_Actor::GEOM_Actor() +{ + this->Device = vtkActor::New(); + + this->WireframeMapper = NULL; + this->ShadingMapper = NULL; + + this->ShadingProperty = NULL; + this->WireframeProperty = NULL; + + this->deflection = 0; + myDisplayMode = 0; + + this->myIO = NULL; + this->myName = ""; + + this->HighlightProperty = NULL; + this->ishighlighted = false; + + this->subshape = false; +} + +GEOM_Actor::~GEOM_Actor() +{ + if (WireframeMapper != NULL) + WireframeMapper->Delete(); + if (ShadingMapper != NULL) + ShadingMapper->Delete(); + if (ShadingProperty != NULL) + ShadingProperty->Delete(); + if (WireframeProperty != NULL) + WireframeProperty->Delete(); + if (HighlightProperty != NULL) + HighlightProperty->Delete(); +} + + +void GEOM_Actor::ShallowCopy(vtkProp *prop) +{ + GEOM_Actor *f = GEOM_Actor::SafeDownCast(prop); + if ( f != NULL ) + { + this->setInputShape(f->getTopo(),f->getDeflection(),f->getDisplayMode()); + this->setName( f->getName() ); + if ( f->hasIO() ) + this->setIO( f->getIO() ); + this->ShadingMapper = NULL; + this->WireframeMapper = NULL; + } else { + this->myIO = NULL; + this->myName = ""; + this->ShadingMapper = NULL; + this->WireframeMapper = NULL; + } + + // Now do superclass + this->SALOME_Actor::ShallowCopy(prop); +} + +//------------------------------------------------------------- +// Set parameters +//------------------------------------------------------------- + + +void GEOM_Actor::setDisplayMode(int thenewmode) { + myDisplayMode = thenewmode; + if ( thenewmode >=1 ) { + if ((myShape.ShapeType() == TopAbs_WIRE) || + (myShape.ShapeType() == TopAbs_EDGE) || + (myShape.ShapeType() == TopAbs_VERTEX)) { + if ( !subshape ) + CreateWireframeMapper(); + else + return; + } else + CreateShadingMapper(); + } else + CreateWireframeMapper(); +} + +void GEOM_Actor::setDeflection(double adef) { + deflection = adef; +} + +void GEOM_Actor::setInputShape(const TopoDS_Shape& aShape,double adef,int imode) { + myShape = aShape; + deflection = adef; + setDisplayMode(imode); +} + +//------------------------------------------------------------- +// Get parameters +//------------------------------------------------------------- + +const TopoDS_Shape& GEOM_Actor::getTopo() { + return myShape; +} + +double GEOM_Actor::getDeflection() { + return deflection; +} + +void GEOM_Actor::SetWireframeProperty(vtkProperty* Prop) { + this->WireframeProperty = Prop; +} + +void GEOM_Actor::SetShadingProperty(vtkProperty* Prop) { + this->ShadingProperty = Prop; +} + + +//------------------------------------------------------------- +// Mapper creating function +//------------------------------------------------------------- +void GEOM_Actor::CreateMapper(int theMode) { + if(myShape.ShapeType() == TopAbs_VERTEX) { + gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(myShape)); + this->SetPosition(aPnt.X(),aPnt.Y(),aPnt.Z()); + } + GEOM_OCCReader* aread = GEOM_OCCReader::New(); + aread->setTopo(myShape); + aread->setDisplayMode(theMode); + aread->GetOutput()->ReleaseDataFlagOn(); + + vtkPolyDataMapper* aMapper = vtkPolyDataMapper::New(); + if (theMode == 0) { + aMapper->SetInput(aread->GetOutput()); + } else { + vtkPolyDataNormals *normals = vtkPolyDataNormals::New(); + normals->SetInput(aread->GetOutput()); + aMapper->SetInput(normals->GetOutput()); + } + aread->Delete(); + this->SetMapper(theMode == 0? WireframeMapper = aMapper : ShadingMapper = aMapper); +} + +void GEOM_Actor::CreateShadingMapper() { + CreateMapper(1); +} + + +void GEOM_Actor::CreateWireframeMapper() { + CreateMapper(0); +} + +//------------------------------------------------------------- +// Render function +//------------------------------------------------------------- + +void GEOM_Actor::Render(vtkRenderer *ren, vtkMapper *Mapper) +{ + /* render the property */ + if (!this->Property) { + // force creation of a property + this->GetProperty(); + this->Property->SetInterpolation(1); + this->Property->SetRepresentationToSurface(); + this->Property->SetAmbient(0.3); + this->Property->SetAmbientColor(0.88,0.86,0.2); + this->Property->SetDiffuseColor(0.99,0.7,0.21); + this->Property->SetSpecularColor(0.99,0.98,0.83); + } + + if(!ishighlighted) { + if(myDisplayMode >= 1) { + // SHADING + this->Property = ShadingProperty; + } + else { + this->Property = WireframeProperty; + } + + if ( ispreselected ) + this->Property = PreviewProperty; + } + + this->Property->Render(this, ren); + if (this->BackfaceProperty) { + this->BackfaceProperty->BackfaceRender(this, ren); + this->Device->SetBackfaceProperty(this->BackfaceProperty); + } + this->Device->SetProperty(this->Property); + // Store information on time it takes to render. + // We might want to estimate time from the number of polygons in mapper. + if(myDisplayMode >= 1) { + if((myShape.ShapeType() == TopAbs_WIRE) || + (myShape.ShapeType() == TopAbs_EDGE) || + (myShape.ShapeType() == TopAbs_VERTEX)) { + if ( !subshape ) { + if(WireframeMapper==NULL) CreateWireframeMapper(); + } else + return; + } + else { + if(ShadingMapper==NULL) CreateShadingMapper(); + } + } + else { + if(WireframeMapper==NULL) CreateWireframeMapper(); + } + if(myShape.ShapeType() == TopAbs_VERTEX) { + if(ren){ + //The parameter determine size of vertex actor relate to diagonal of RendererWindow + static float delta = 0.01; + float X1 = -1, Y1 = -1, Z1 = 0; + ren->ViewToWorld(X1,Y1,Z1); + float X2 = +1, Y2 = +1, Z2 = 0; + ren->ViewToWorld(X2,Y2,Z2); + Z2 = sqrt((X2-X1)*(X2-X1) + (Y2-Y1)*(Y2-Y1) + (Z2-Z1)*(Z2-Z1)); + this->SetScale(Z2*delta); + } + vtkMatrix4x4 *aMatrix = vtkMatrix4x4::New(); + this->GetMatrix(ren->GetActiveCamera(), aMatrix); + this->Device->SetUserMatrix(aMatrix); + this->Device->Render(ren,this->Mapper); + aMatrix->Delete(); + } else + this->Device->Render(ren, this->Mapper); + this->EstimatedRenderTime = WireframeMapper->GetTimeToDraw(); +} + +// SubShape +void GEOM_Actor::SubShapeOn() +{ + subshape = true; +} +void GEOM_Actor::SubShapeOff() +{ + subshape = false; +} + +//------------------------------------------------------------- +// Opacity methods +//------------------------------------------------------------- + +void GEOM_Actor::SetOpacity(float opa) +{ + //HighlightProperty->SetOpacity(opa); + SALOME_Actor::SetOpacity(opa); + ShadingProperty->SetOpacity(opa); +} + +float GEOM_Actor::GetOpacity() { + return ShadingProperty->GetOpacity(); +} + +//------------------------------------------------------------- +// Color methods +//------------------------------------------------------------- +void GEOM_Actor::SetColor(float r,float g,float b) { + ShadingProperty->SetColor(r,g,b); +} + +void GEOM_Actor::GetColor(float& r,float& g,float& b) { + float color[3]; + ShadingProperty->GetColor(color); + r = color[0]; + g = color[1]; + b = color[2]; +} + +//------------------------------------------------------------- +// Highlight methods +//------------------------------------------------------------- + +void GEOM_Actor::highlight(Standard_Boolean highlight) { + + if(highlight && !ishighlighted) { + ishighlighted=true; + // build highlight property is necessary + if(HighlightProperty==NULL) { + HighlightProperty = vtkProperty::New(); + HighlightProperty->SetAmbient(0.5); + HighlightProperty->SetDiffuse(0.3); + HighlightProperty->SetSpecular(0.2); + HighlightProperty->SetRepresentationToSurface(); + HighlightProperty->SetAmbientColor(1, 1, 1); + HighlightProperty->SetDiffuseColor(1, 1, 1); + HighlightProperty->SetSpecularColor(0.5, 0.5, 0.5); + } + + this->Property = HighlightProperty; + + } + else if (!highlight) { + if(ishighlighted) { + ishighlighted=false; + if(myDisplayMode==1) { + //unhilight in shading + this->Property = ShadingProperty; + } + else { + //unhilight in wireframe + this->Property = WireframeProperty; + } + } + } +} + +bool GEOM_Actor::hasHighlight() +{ + return true; +} + +void GEOM_Actor::SetHighlightProperty(vtkProperty* Prop) { + this->HighlightProperty = Prop; +} + + +void GEOM_Actor::ReleaseGraphicsResources(vtkWindow *renWin) +{ + vtkActor::ReleaseGraphicsResources(renWin); + + // broadcast the message down to the individual LOD mappers + + if(WireframeMapper) this->WireframeMapper->ReleaseGraphicsResources(renWin); + if(ShadingMapper) this->ShadingMapper->ReleaseGraphicsResources(renWin); +} + + +// Copy the follower's composite 4x4 matrix into the matrix provided. +void GEOM_Actor::GetMatrix(vtkCamera* theCam, vtkMatrix4x4 *result) +{ + double *pos, *vup; + double Rx[3], Ry[3], Rz[3], p1[3]; + vtkMatrix4x4 *matrix = vtkMatrix4x4::New(); + int i; + double distance; + + this->GetOrientation(); + this->Transform->Push(); + this->Transform->PostMultiply(); + this->Transform->Identity(); + + // apply user defined matrix last if there is one + if (this->UserMatrix) + { + this->Transform->Concatenate(this->UserMatrix); + } + + this->Transform->Translate(-this->Origin[0], + -this->Origin[1], + -this->Origin[2]); + // scale + this->Transform->Scale(this->Scale[0], + this->Scale[1], + this->Scale[2]); + + // rotate + this->Transform->RotateY(this->Orientation[1]); + this->Transform->RotateX(this->Orientation[0]); + this->Transform->RotateZ(this->Orientation[2]); + + if (theCam) + { + // do the rotation + // first rotate y + pos = theCam->GetPosition(); + vup = theCam->GetViewUp(); + + if (theCam->GetParallelProjection()) + { + theCam->GetDirectionOfProjection(Rz); + } + else + { + distance = sqrt( + (pos[0] - this->Position[0])*(pos[0] - this->Position[0]) + + (pos[1] - this->Position[1])*(pos[1] - this->Position[1]) + + (pos[2] - this->Position[2])*(pos[2] - this->Position[2])); + for (i = 0; i < 3; i++) + { + Rz[i] = (pos[i] - this->Position[i])/distance; + } + } + + vtkMath::Cross(vup,Rz,Rx); + vtkMath::Normalize(Rx); + vtkMath::Cross(Rz,Rx,Ry); + + matrix->Element[0][0] = Rx[0]; + matrix->Element[1][0] = Rx[1]; + matrix->Element[2][0] = Rx[2]; + matrix->Element[0][1] = Ry[0]; + matrix->Element[1][1] = Ry[1]; + matrix->Element[2][1] = Ry[2]; + matrix->Element[0][2] = Rz[0]; + matrix->Element[1][2] = Rz[1]; + matrix->Element[2][2] = Rz[2]; + + this->Transform->Concatenate(matrix); + } + + // translate to projection reference point PRP + // this is the camera's position blasted through + // the current matrix + p1[0] = this->Origin[0] + this->Position[0]; + p1[1] = this->Origin[1] + this->Position[1]; + p1[2] = this->Origin[2] + this->Position[2]; + + this->Transform->Translate(p1[0],p1[1],p1[2]); + this->Transform->GetMatrix(result); + + matrix->Delete(); + this->Transform->Pop(); +} diff --git a/OBJECT/GEOM_Actor.h b/OBJECT/GEOM_Actor.h new file mode 100644 index 000000000..c40dd1001 --- /dev/null +++ b/OBJECT/GEOM_Actor.h @@ -0,0 +1,125 @@ +// GEOM OBJECT : interactive object for Geometry entities visualization +// +// 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 +// +// +// +// File : GEOM_Actor.h +// Author : Christophe ATTANASIO +// Module : GEOM +// $Header$ + +#ifndef GEOM_ACTOR_H +#define GEOM_ACTOR_H + +#include "SALOME_Actor.h" + +//OpenCASCADE +#include +#include + + +class TopoDS_Shape; + +#ifdef _WIN_32 +#define VTKOCC_EXPORT __declspec (dllexport) +#else +#define VTKOCC_EXPORT +#endif +class VTKOCC_EXPORT GEOM_Actor : public SALOME_Actor { + + + public: + vtkTypeMacro(GEOM_Actor,SALOME_Actor); + + static GEOM_Actor* New(); + + // Description: + // This causes the actor to be rendered. It, in turn, will render the actor's + // property and then mapper. + virtual void Render(vtkRenderer *, vtkMapper *); + + // Description: + // Release any graphics resources that are being consumed by this actor. + // The parameter window could be used to determine which graphic + // resources to release. + void ReleaseGraphicsResources(vtkWindow *); + + const TopoDS_Shape& getTopo(); + void setInputShape(const TopoDS_Shape& ashape,double adef1,int imode); + + double getDeflection(); + void setDeflection(double adefl); + + // SubShape + void SubShapeOn(); + void SubShapeOff(); + + // Display Mode + void setDisplayMode(int); + + // Highlight + void highlight(Standard_Boolean highlight); + bool hasHighlight(); + + void ShallowCopy(vtkProp *prop); + + // Properties + void SetHighlightProperty(vtkProperty* Prop); + void SetWireframeProperty(vtkProperty* Prop); + void SetShadingProperty(vtkProperty* Prop); + + // Opacity + void SetOpacity(float opa); + float GetOpacity(); + + // Color + void SetColor(float r,float g,float b); + void GetColor(float& r,float& g,float& b); + + protected: + + GEOM_Actor(); + ~GEOM_Actor(); + GEOM_Actor(const GEOM_Actor&) {}; + void operator=(const GEOM_Actor&) {}; + + void CreateWireframeMapper(); + void CreateShadingMapper(); + void CreateMapper(int theMode); + void GetMatrix(vtkCamera* theCam, vtkMatrix4x4 *result); + + + private: + + bool subshape; + + TopoDS_Shape myShape; + double deflection; + + vtkMapper* ShadingMapper; + vtkMapper* WireframeMapper; + + vtkProperty* ShadingProperty; + vtkProperty* WireframeProperty; + vtkProperty* HighlightProperty; + +}; +#endif //GEOM_ACTOR_H diff --git a/OBJECT/GEOM_AssemblyBuilder.cxx b/OBJECT/GEOM_AssemblyBuilder.cxx new file mode 100644 index 000000000..39aca3d9c --- /dev/null +++ b/OBJECT/GEOM_AssemblyBuilder.cxx @@ -0,0 +1,421 @@ +// GEOM OBJECT : interactive object for Geometry entities visualization +// +// 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 +// +// +// +// File : GEOM_AssemblyBuilder.cxx +// Author : Christophe ATTANASIO +// Module : GEOM +// $Header$ + +using namespace std; +/*! + \class GEOM_AssemblyBuilder GEOM_AssemblyBuilder.h + \brief .... +*/ + +#include "GEOM_AssemblyBuilder.h" +#include "GEOM_Actor.h" +#include "utilities.h" + +// Open CASCADE Includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// SALOME + +#define MAX2(X, Y) ( Abs(X) > Abs(Y)? Abs(X) : Abs(Y) ) +#define MAX3(X, Y, Z) ( MAX2 ( MAX2(X,Y) , Z) ) + + + + + +void GEOM_AssemblyBuilder::InitProperties(vtkProperty* IsoProp, + vtkProperty* FaceProp, + vtkProperty* EdgeFProp, + vtkProperty* EdgeSProp, + vtkProperty* EdgeIProp, + vtkProperty* VertexProp, + vtkProperty* IsoPVProp, + vtkProperty* EdgePVProp, + vtkProperty* VertexPVProp) +{ + // Shading like default OCC material + FaceProp->SetRepresentationToSurface(); + FaceProp->SetInterpolation(1); + FaceProp->SetAmbient(1.0); + FaceProp->SetDiffuse(1.0); + FaceProp->SetSpecular(0.4); + FaceProp->SetAmbientColor(0.329412, 0.223529, 0.027451); + FaceProp->SetDiffuseColor(0.780392, 0.568627, 0.113725); + FaceProp->SetSpecularColor(0.992157, 0.941176, 0.807843); + + // Wireframe for iso + IsoProp->SetRepresentationToWireframe(); + IsoProp->SetAmbientColor(0.5, 0.5, 0.5); + IsoProp->SetDiffuseColor(0.5, 0.5, 0.5); + IsoProp->SetSpecularColor(0.5, 0.5, 0.5); + + // Wireframe for iso + IsoPVProp->SetRepresentationToWireframe(); + IsoPVProp->SetAmbientColor(0, 1, 1); + IsoPVProp->SetDiffuseColor(0, 1, 1); + IsoPVProp->SetSpecularColor(0, 1, 1); + + // Wireframe for shared edge + EdgeSProp->SetRepresentationToWireframe(); + EdgeSProp->SetAmbientColor(1, 1, 0); + EdgeSProp->SetDiffuseColor(1, 1, 0); + EdgeSProp->SetSpecularColor(1, 1, 0); + + // Wireframe for free edge + EdgeFProp->SetRepresentationToWireframe(); + EdgeFProp->SetAmbientColor(0, 1, 0); + EdgeFProp->SetDiffuseColor(0, 1, 0); + EdgeFProp->SetSpecularColor(0, 1, 0); + + // Wireframe for isolated edge + EdgeIProp->SetRepresentationToWireframe(); + EdgeIProp->SetAmbientColor(1, 0, 0); + EdgeIProp->SetDiffuseColor(1, 0, 0); + EdgeIProp->SetSpecularColor(1, 0, 0); + + // Wireframe for Preview edge + EdgePVProp->SetRepresentationToWireframe(); + EdgePVProp->SetAmbientColor(0, 1, 1); + EdgePVProp->SetDiffuseColor(0, 1, 1); + EdgePVProp->SetSpecularColor(0, 1, 1); + + // Wireframe for vertex + VertexProp->SetRepresentationToWireframe(); + VertexProp->SetAmbientColor(1, 1, 0); + VertexProp->SetDiffuseColor(1, 1, 0); + VertexProp->SetSpecularColor(1, 1, 0); + + // Wireframe for vertex + VertexPVProp->SetRepresentationToWireframe(); + VertexPVProp->SetAmbientColor(0, 1, 1); + VertexPVProp->SetDiffuseColor(0, 1, 1); + VertexPVProp->SetSpecularColor(0, 1, 1); +} + + +void GEOM_AssemblyBuilder::MeshShape(const TopoDS_Shape myShape, + Standard_Real deflection, + Standard_Boolean forced) +{ + // Mesh the shape if necessary + Standard_Boolean alreadymesh = Standard_True; + TopExp_Explorer ex; + TopLoc_Location aLoc; + + for (ex.Init(myShape, TopAbs_FACE); ex.More(); ex.Next()) { + const TopoDS_Face& aFace = TopoDS::Face(ex.Current()); + Handle(Poly_Triangulation) aPoly = BRep_Tool::Triangulation(aFace,aLoc); + if(aPoly.IsNull()) { alreadymesh = Standard_False; break; } + } + + if(!alreadymesh || forced) { + if(deflection<=0) { + // Compute default deflection + Bnd_Box B; + BRepBndLib::Add(myShape, B); + Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax; + B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); + deflection = MAX3( aXmax-aXmin , aYmax-aYmin , aZmax-aZmin) * 0.001 *4; + } + BRepMesh_IncrementalMesh MESH(myShape,deflection); + } +} + + + +vtkActorCollection* GEOM_AssemblyBuilder::BuildActors(const TopoDS_Shape& myShape, + Standard_Real deflection, + Standard_Integer mode, + Standard_Boolean forced) { + + vtkActorCollection* AISActors = vtkActorCollection::New(); + + if(myShape.ShapeType() == TopAbs_COMPOUND) { + TopoDS_Iterator anItr(myShape); + for(; anItr.More(); anItr.Next()) { + vtkActorCollection* theActors = GEOM_AssemblyBuilder::BuildActors(anItr.Value(), deflection, mode, forced); + theActors->InitTraversal(); + vtkActor* anActor = (vtkActor*)theActors->GetNextActor(); + while(!(anActor==NULL)) { + AISActors->AddItem(anActor); + anActor = (vtkActor*)theActors->GetNextActor(); + } + } + } + // Create graphics properties + + vtkProperty* IsoProp = vtkProperty::New(); + vtkProperty* FaceProp = vtkProperty::New(); + vtkProperty* EdgeFProp = vtkProperty::New(); + vtkProperty* EdgeSProp = vtkProperty::New(); + vtkProperty* EdgeIProp = vtkProperty::New(); + vtkProperty* VertexProp = vtkProperty::New(); + + vtkProperty* IsoPVProp = vtkProperty::New(); + vtkProperty* EdgePVProp = vtkProperty::New(); + vtkProperty* VertexPVProp = vtkProperty::New(); + + InitProperties(IsoProp,FaceProp,EdgeFProp,EdgeSProp,EdgeIProp,VertexProp,IsoPVProp,EdgePVProp,VertexPVProp); + + MeshShape(myShape,deflection,forced); + + if ( myShape.ShapeType() <= 4 && myShape.ShapeType() != TopAbs_COMPOUND) { + + // FACE Actor + // look if edges are free or shared + TopTools_IndexedDataMapOfShapeListOfShape edgemap; + TopExp::MapShapesAndAncestors(myShape,TopAbs_EDGE,TopAbs_FACE,edgemap); + + TopExp_Explorer ex; + + for (ex.Init(myShape, TopAbs_FACE); ex.More(); ex.Next()) { + + GEOM_Actor* FaceActor = GEOM_Actor::New(); + FaceActor->SetShadingProperty(FaceProp); + FaceActor->SetWireframeProperty(IsoProp); + + FaceActor->SetPreviewProperty(IsoPVProp); + + FaceActor->setInputShape(ex.Current(),deflection,mode); + + AISActors->AddItem(FaceActor); + + TopExp_Explorer ex2; + for (ex2.Init(ex.Current(), TopAbs_EDGE); ex2.More(); ex2.Next()) { + const TopoDS_Edge& aEdge = TopoDS::Edge(ex2.Current()); + + if (BRep_Tool::Degenerated(aEdge)) { + continue; + } + + // compute the number of faces + Standard_Integer nbf = edgemap.FindFromKey(ex2.Current()).Extent(); + GEOM_Actor* EdgeActor = GEOM_Actor::New(); + EdgeActor->SubShapeOn(); + EdgeActor->setInputShape(ex2.Current(),deflection,mode); + switch (nbf) { + + case 0 : // isolated edge + { + EdgeActor->SetShadingProperty(EdgeIProp); + EdgeActor->SetWireframeProperty(EdgeIProp); + } + break; + + case 1 :// edge in only one face + { + EdgeActor->SetShadingProperty(EdgeFProp); + EdgeActor->SetWireframeProperty(EdgeFProp); + } + break; + + default : // edge shared by at least two faces + { + EdgeActor->SetShadingProperty(EdgeSProp); + EdgeActor->SetWireframeProperty(EdgeSProp); + } + } + EdgeActor->SetPreviewProperty(EdgePVProp); + AISActors->AddItem(EdgeActor); + } + } + } else if ( myShape.ShapeType() == TopAbs_WIRE ) { // WIRE Actor + TopExp_Explorer ex; + for (ex.Init(myShape, TopAbs_EDGE); ex.More(); ex.Next()) { + const TopoDS_Edge& aEdge = TopoDS::Edge(ex.Current()); + + if (BRep_Tool::Degenerated(aEdge)) { + continue; + } + + GEOM_Actor* EdgeActor = GEOM_Actor::New(); + EdgeActor->setInputShape(ex.Current(),deflection,mode); + EdgeActor->SetShadingProperty(EdgeIProp); + EdgeActor->SetWireframeProperty(EdgeIProp); + EdgeActor->SetPreviewProperty(EdgePVProp); + + AISActors->AddItem(EdgeActor); + } + } else if ( myShape.ShapeType() == TopAbs_EDGE ) { // EDGE Actor + GEOM_Actor* EdgeActor = GEOM_Actor::New(); + EdgeActor->setInputShape(myShape,deflection,mode); + EdgeActor->SetShadingProperty(EdgeIProp); + EdgeActor->SetWireframeProperty(EdgeIProp); + EdgeActor->SetPreviewProperty(EdgePVProp); + + AISActors->AddItem(EdgeActor); + } else if ( myShape.ShapeType() == TopAbs_VERTEX ) { // VERTEX Actor + GEOM_Actor* VertexActor = GEOM_Actor::New(); + VertexActor->setInputShape(myShape,deflection,mode); + VertexActor->SetShadingProperty(VertexProp); + VertexActor->SetWireframeProperty(VertexProp); + VertexActor->SetPreviewProperty(VertexPVProp); + + AISActors->AddItem(VertexActor); + + } + + return AISActors; + +} + + + +//------------------------------------------------------------- +// BUILD ASSEMBLY +//------------------------------------------------------------- +vtkAssembly* GEOM_AssemblyBuilder::BuildAssembly(const TopoDS_Shape& myShape, + Standard_Real deflection, + Standard_Integer mode, + Standard_Boolean forced) +{ + // Create a new vtkAssembly + + vtkAssembly* myVTKShape = vtkAssembly::New(); + + + // Create graphics properties + + vtkProperty* IsoProp = vtkProperty::New(); + vtkProperty* FaceProp = vtkProperty::New(); + vtkProperty* EdgeFProp = vtkProperty::New(); + vtkProperty* EdgeSProp = vtkProperty::New(); + vtkProperty* EdgeIProp = vtkProperty::New(); + vtkProperty* VertexProp = vtkProperty::New(); + vtkProperty* EdgePVProp = vtkProperty::New(); + vtkProperty* VertexPVProp = vtkProperty::New(); + vtkProperty* IsoPVProp = vtkProperty::New(); + + InitProperties(IsoProp,FaceProp,EdgeFProp,EdgeSProp,EdgeIProp,VertexProp,IsoPVProp,EdgePVProp,VertexPVProp); + + MeshShape(myShape,deflection,forced); + + + // FACE Actor + + // look if edges are free or shared + TopTools_IndexedDataMapOfShapeListOfShape edgemap; + TopExp::MapShapesAndAncestors(myShape,TopAbs_EDGE,TopAbs_FACE,edgemap); + + TopExp_Explorer ex; + + for (ex.Init(myShape, TopAbs_FACE); ex.More(); ex.Next()) { + //const TopoDS_Face& aFace = TopoDS::Face(ex.Current()); + + GEOM_Actor* FaceActor = GEOM_Actor::New(); + FaceActor->SetShadingProperty(FaceProp); + FaceActor->SetWireframeProperty(IsoProp); + + vtkAssembly* myFaceAssembly = vtkAssembly::New(); + + + FaceActor->setInputShape(ex.Current(),deflection,mode); + myFaceAssembly->AddPart(FaceActor); + + TopExp_Explorer ex2; + for (ex2.Init(ex.Current(), TopAbs_EDGE); ex2.More(); ex2.Next()) { + const TopoDS_Edge& aEdge = TopoDS::Edge(ex2.Current()); + + if (BRep_Tool::Degenerated(aEdge)) { + continue; + } + + + // compute the number of faces + Standard_Integer nbf = edgemap.FindFromKey(ex2.Current()).Extent(); + GEOM_Actor* EdgeActor = GEOM_Actor::New(); + switch (nbf) { + + case 0 : // isolated edge + { + EdgeActor->SetShadingProperty(EdgeIProp); + EdgeActor->SetWireframeProperty(EdgeIProp); + } + break; + + case 1 :// edge in only one face + { + EdgeActor->SetShadingProperty(EdgeFProp); + EdgeActor->SetWireframeProperty(EdgeFProp); + } + break; + + default : // edge shared by at least two faces + { + EdgeActor->SetShadingProperty(EdgeSProp); + EdgeActor->SetWireframeProperty(EdgeSProp); + } + } + + EdgeActor->setInputShape(ex2.Current(),deflection,mode); + myFaceAssembly->AddPart(EdgeActor); + } + myVTKShape->AddPart(myFaceAssembly); + } + + return myVTKShape; + +} + +//------------------------------------------------------------- +// CHANGE SPECIFIC DISPLAY MODE +//------------------------------------------------------------- +void GEOM_AssemblyBuilder::SwitchDisplayMode(vtkAssembly* aOCCAssembly) +{ +} + +void GEOM_AssemblyBuilder::SwitchDisplayMode(vtkActorCollection* aOCCAssembly) +{ +} + +//------------------------------------------------------------- +// DISPLAY/ERASE +//------------------------------------------------------------- + +void GEOM_AssemblyBuilder::DisplayErase(vtkAssembly* mySALOMEAssembly) +{ +} + + +void GEOM_AssemblyBuilder::DisplayErase(vtkActorCollection* mySALOMEActors) +{ +} + + + + + diff --git a/OBJECT/GEOM_AssemblyBuilder.h b/OBJECT/GEOM_AssemblyBuilder.h new file mode 100644 index 000000000..a396b9e25 --- /dev/null +++ b/OBJECT/GEOM_AssemblyBuilder.h @@ -0,0 +1,93 @@ +// GEOM OBJECT : interactive object for Geometry entities visualization +// +// 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 +// +// +// +// File : GEOM_AssemblyBuilder.h +// Author : Christophe ATTANASIO +// Module : GEOM +// $Header$ + +#include +#include +#include + +// Open CASCADE Inlcudes +#include +#include + +class GEOM_AssemblyBuilder { + + private: + + static void InitProperties(vtkProperty* IsoProp, + vtkProperty* FaceProp, + vtkProperty* EdgeFProp, + vtkProperty* EdgeSProp, + vtkProperty* EdgeIProp, + vtkProperty* VertexProp, + vtkProperty* IsoPVProp, + vtkProperty* EdgePVProp, + vtkProperty* VertePVProp); + + static void MeshShape(const TopoDS_Shape myShape, + Standard_Real deflection, + Standard_Boolean forced); + + + public: + + + //------------------------------------------------------------------ + // WARNING! Poor graphic performance :-( use BuildActors instead + //------------------------------------------------------------------ + + static vtkAssembly* BuildAssembly(const TopoDS_Shape& myShape, + Standard_Real deflection, + Standard_Integer amode, + Standard_Boolean forced); + + //------------------------------------------------------------------ + // Good performance + //------------------------------------------------------------------ + + static vtkActorCollection* BuildActors(const TopoDS_Shape& myShape, + Standard_Real deflection, + Standard_Integer amode, + Standard_Boolean forced); + + + //------------------------------------------------------------------ + // Change mode - Not implemented !! + //------------------------------------------------------------------ + + static void SwitchDisplayMode(vtkAssembly* mySALOMEAssembly); + static void SwitchDisplayMode(vtkActorCollection* mySALOMEActors); + + //------------------------------------------------------------------ + // Erase/Display - Not implemented !! + //------------------------------------------------------------------ + + static void DisplayErase(vtkAssembly* mySALOMEAssembly); + static void DisplayErase(vtkActorCollection* mySALOMEActors); + + +}; diff --git a/OBJECT/GEOM_InteractiveObject.cxx b/OBJECT/GEOM_InteractiveObject.cxx new file mode 100644 index 000000000..892cd143c --- /dev/null +++ b/OBJECT/GEOM_InteractiveObject.cxx @@ -0,0 +1,76 @@ +// GEOM OBJECT : interactive object for Geometry entities visualization +// +// 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 +// +// +// +// File : GEOM_InteractiveObject.cxx +// Author : Christophe ATTANASIO +// Module : GEOM +// $Header$ + +using namespace std; +/*! + \class GEOM_InteractiveObject GEOM_InteractiveObject.hxx + \brief .... +*/ + +#include "GEOM_InteractiveObject.ixx" + +GEOM_InteractiveObject::GEOM_InteractiveObject() + : SALOME_InteractiveObject() +{ + myIOR = ""; + myFatherIOR = ""; +} + +GEOM_InteractiveObject::GEOM_InteractiveObject(const Standard_CString anIOR, + const Standard_CString aFatherIOR, + const Standard_CString aComponentDataType, + const Standard_CString anEntry) + : SALOME_InteractiveObject(anEntry,aComponentDataType) +{ + myIOR = new char [strlen(anIOR)+1]; + strcpy( myIOR, anIOR); + myFatherIOR = new char [strlen(aFatherIOR)+1]; + strcpy( myFatherIOR, aFatherIOR); +} + +Standard_CString GEOM_InteractiveObject::getIOR(){ + return myIOR; +} +Standard_CString GEOM_InteractiveObject::getFatherIOR(){ + return myFatherIOR; +} + +Standard_Boolean GEOM_InteractiveObject::isSame(const Handle(SALOME_InteractiveObject)& anIO ){ + if ( anIO->hasEntry() && this->hasEntry() ) { + if ( strcmp(myEntry, anIO->getEntry() ) == 0 ) + return Standard_True; + } + + if ( anIO->IsKind(STANDARD_TYPE(GEOM_InteractiveObject))) { + Handle(GEOM_InteractiveObject) theIO = Handle(GEOM_InteractiveObject)::DownCast( anIO ); + if ( strcmp(myIOR, theIO->getIOR() ) == 0 ) + return Standard_True; + } + + return Standard_False; +} diff --git a/OBJECT/GEOM_InteractiveObject.hxx b/OBJECT/GEOM_InteractiveObject.hxx new file mode 100644 index 000000000..a14c40783 --- /dev/null +++ b/OBJECT/GEOM_InteractiveObject.hxx @@ -0,0 +1,127 @@ +// GEOM OBJECT : interactive object for Geometry entities visualization +// +// 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 +// +// +// +// File : GEOM_InteractiveObject.hxx +// Module : GEOM + +#ifndef _GEOM_InteractiveObject_HeaderFile +#define _GEOM_InteractiveObject_HeaderFile + +#ifndef _Standard_HeaderFile +#include +#endif +#ifndef _Handle_GEOM_InteractiveObject_HeaderFile +#include "Handle_GEOM_InteractiveObject.hxx" +#endif + +#ifndef _Standard_CString_HeaderFile +#include +#endif +#ifndef _SALOME_InteractiveObject_HeaderFile +#include "SALOME_InteractiveObject.hxx" +#endif +#ifndef _Standard_Boolean_HeaderFile +#include +#endif +#ifndef _Handle_SALOME_InteractiveObject_HeaderFile +#include "Handle_SALOME_InteractiveObject.hxx" +#endif +class SALOME_InteractiveObject; + + +class GEOM_InteractiveObject : public SALOME_InteractiveObject { + +public: + + inline void* operator new(size_t,void* anAddress) + { + return anAddress; + } + inline void* operator new(size_t size) + { + return Standard::Allocate(size); + } + inline void operator delete(void *anAddress) + { + if (anAddress) Standard::Free((Standard_Address&)anAddress); + } +// inline void operator delete(void *anAddress, size_t size) +// { +// if (anAddress) Standard::Free((Standard_Address&)anAddress,size); +// } + // Methods PUBLIC + // +Standard_EXPORT GEOM_InteractiveObject(); +Standard_EXPORT GEOM_InteractiveObject(const Standard_CString anIOR, + const Standard_CString aFatherIOR, + const Standard_CString aComponentDataType, + const Standard_CString anEntry = ""); +Standard_EXPORT void setIOR(const Standard_CString anEntry) ; +Standard_EXPORT Standard_CString getIOR() ; +Standard_EXPORT void setFatherIOR(const Standard_CString anEntry) ; +Standard_EXPORT Standard_CString getFatherIOR() ; +Standard_EXPORT virtual Standard_Boolean isSame(const Handle(SALOME_InteractiveObject)& anIO) ; +Standard_EXPORT ~GEOM_InteractiveObject(); + + + + + // Type management + // + Standard_EXPORT friend Handle_Standard_Type& GEOM_InteractiveObject_Type_(); + Standard_EXPORT const Handle(Standard_Type)& DynamicType() const; + Standard_EXPORT Standard_Boolean IsKind(const Handle(Standard_Type)&) const; + +protected: + + // Methods PROTECTED + // + + + // Fields PROTECTED + // + + +private: + + // Methods PRIVATE + // + + + // Fields PRIVATE + // +Standard_CString myIOR; +Standard_CString myFatherIOR; + + +}; + + + + + +// other inline functions and methods (like "C++: function call" methods) +// + + +#endif diff --git a/OBJECT/GEOM_InteractiveObject.ixx b/OBJECT/GEOM_InteractiveObject.ixx new file mode 100644 index 000000000..dccdbb94b --- /dev/null +++ b/OBJECT/GEOM_InteractiveObject.ixx @@ -0,0 +1,83 @@ +// GEOM OBJECT : interactive object for Geometry entities visualization +// +// 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 +// +// +// +// File : GEOM_InteractiveObject.ixx +// Module : GEOM + +#include "GEOM_InteractiveObject.jxx" + +#ifndef _Standard_TypeMismatch_HeaderFile +#include +#endif + +GEOM_InteractiveObject::~GEOM_InteractiveObject() {} + + + +Standard_EXPORT Handle_Standard_Type& GEOM_InteractiveObject_Type_() +{ + + static Handle_Standard_Type aType1 = STANDARD_TYPE(SALOME_InteractiveObject); + if ( aType1.IsNull()) aType1 = STANDARD_TYPE(SALOME_InteractiveObject); + static Handle_Standard_Type aType2 = STANDARD_TYPE(MMgt_TShared); + if ( aType2.IsNull()) aType2 = STANDARD_TYPE(MMgt_TShared); + static Handle_Standard_Type aType3 = STANDARD_TYPE(Standard_Transient); + if ( aType3.IsNull()) aType3 = STANDARD_TYPE(Standard_Transient); + + + static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,NULL}; + static Handle_Standard_Type _aType = new Standard_Type("GEOM_InteractiveObject", + sizeof(GEOM_InteractiveObject), + 1, + (Standard_Address)_Ancestors, + (Standard_Address)NULL); + + return _aType; +} + + +// DownCast method +// allow safe downcasting +// +const Handle(GEOM_InteractiveObject) Handle(GEOM_InteractiveObject)::DownCast(const Handle(Standard_Transient)& AnObject) +{ + Handle(GEOM_InteractiveObject) _anOtherObject; + + if (!AnObject.IsNull()) { + if (AnObject->IsKind(STANDARD_TYPE(GEOM_InteractiveObject))) { + _anOtherObject = Handle(GEOM_InteractiveObject)((Handle(GEOM_InteractiveObject)&)AnObject); + } + } + + return _anOtherObject ; +} +const Handle(Standard_Type)& GEOM_InteractiveObject::DynamicType() const +{ + return STANDARD_TYPE(GEOM_InteractiveObject) ; +} +Standard_Boolean GEOM_InteractiveObject::IsKind(const Handle(Standard_Type)& AType) const +{ + return (STANDARD_TYPE(GEOM_InteractiveObject) == AType || SALOME_InteractiveObject::IsKind(AType)); +} +Handle_GEOM_InteractiveObject::~Handle_GEOM_InteractiveObject() {} + diff --git a/OBJECT/GEOM_InteractiveObject.jxx b/OBJECT/GEOM_InteractiveObject.jxx new file mode 100644 index 000000000..8884bdc8b --- /dev/null +++ b/OBJECT/GEOM_InteractiveObject.jxx @@ -0,0 +1,32 @@ +// GEOM OBJECT : interactive object for Geometry entities visualization +// +// 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 +// +// +// +// File : GEOM_InteractiveObject.jxx +// Module : GEOM + +#ifndef _SALOME_InteractiveObject_HeaderFile +#include "SALOME_InteractiveObject.hxx" +#endif +#ifndef _GEOM_InteractiveObject_HeaderFile +#include "GEOM_InteractiveObject.hxx" +#endif diff --git a/OBJECT/GEOM_OCCReader.cxx b/OBJECT/GEOM_OCCReader.cxx new file mode 100644 index 000000000..500fdd356 --- /dev/null +++ b/OBJECT/GEOM_OCCReader.cxx @@ -0,0 +1,988 @@ +// GEOM OBJECT : interactive object for Geometry entities visualization +// +// 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 +// +// +// +// File : GEOM_OCCReader.h +// Author : Christophe ATTANASIO +// Module : GEOM +// $Header$ + +using namespace std; +#include "GEOM_OCCReader.h" + +// SALOME Includes +#include "utilities.h" + +// VTK Includes +#include "VTKViewer_Common.h" +#include + +// OpenCASCADE Includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define MAX2(X, Y) ( Abs(X) > Abs(Y)? Abs(X) : Abs(Y) ) +#define MAX3(X, Y, Z) ( MAX2 ( MAX2(X,Y) , Z) ) + +// Constante for iso building +static Standard_Real IntersectorConfusion = 1.e-10 ; // -8 ; +static Standard_Real IntersectorTangency = 1.e-10 ; // -8 ; +static Standard_Real HatcherConfusion2d = 1.e-8 ; +static Standard_Real HatcherConfusion3d = 1.e-8 ; + +static Standard_Integer lastVTKpoint = 0; +static Standard_Integer PlotCount = 0; +static Standard_Real IsoRatio = 1.001; +static Standard_Integer MaxPlotCount = 5; + +//======================================================================= +// Function : New +// Purpose : +//======================================================================= + +GEOM_OCCReader* GEOM_OCCReader::New() +{ + vtkObject* ret = vtkObjectFactory::CreateInstance("GEOM_OCCReader"); + if(ret) { + return (GEOM_OCCReader*)ret; + } + return new GEOM_OCCReader; +} + +//======================================================================= +// Function : GEOM_OCCReader +// Purpose : +//======================================================================= + +GEOM_OCCReader::GEOM_OCCReader() +{ + //this->myShape = NULL; + this->amode = 0; + this->forced = Standard_False; + this->discretiso = 15; + this->nbisos = 1; +} +//======================================================================= +// Function : ~GEOM_OCCReader +// Purpose : +//======================================================================= + +GEOM_OCCReader::~GEOM_OCCReader() +{ +} + + +//======================================================================= +// Function : Execute +// Purpose : +//======================================================================= + + +void GEOM_OCCReader::Execute() { + + vtkPolyData* output = this->GetOutput(); + vtkPoints* Pts = NULL; + vtkCellArray* Cells = NULL; + TopLoc_Location aLoc; + + // Allocation + Pts = vtkPoints::New(); + Cells = vtkCellArray::New(); + + //Compute number of triangles and points + Standard_Integer nbpoly=0,nbpts=0; + + if(amode==1) { + //for shading + + if(myShape.ShapeType() == TopAbs_FACE) { + // whole FACE + const TopoDS_Face& aFace = TopoDS::Face(myShape); + Handle(Poly_Triangulation) aPoly = BRep_Tool::Triangulation(aFace,aLoc); + if(aPoly.IsNull()) { + Pts->Delete(); + Cells->Delete(); + return; + } + + nbpts = aPoly->NbNodes(); + nbpoly = aPoly->NbTriangles(); + + Pts->SetNumberOfPoints(nbpts); + Cells->Allocate(Cells->EstimateSize(nbpoly,3)); + } + else { + Cells->Delete(); + Pts->Delete(); + return; + } + } + + // Start computation + if(amode == 0) { + ComputeWireframe(Pts,Cells); + output->SetPoints(Pts); + output->SetLines(Cells); + output->Squeeze(); + } + else { + if(myShape.ShapeType() == TopAbs_FACE) { + ComputeShading(Pts,Cells); + + output->SetPoints(Pts); + output->SetPolys(Cells); + output->Squeeze(); + } + } + Pts->Delete(); + Cells->Delete(); + +} + +//======================================================================= +// Function : ComputeWireframe +// Purpose : Compute the shape in CAD wireframe mode +//======================================================================= + +void GEOM_OCCReader::ComputeWireframe(vtkPoints* Pts,vtkCellArray* Cells){ + + // Check the type of the shape: + if(myShape.ShapeType() == TopAbs_FACE) { + // Face + TransferFaceWData(TopoDS::Face(myShape),Pts,Cells); + } else if(myShape.ShapeType() == TopAbs_EDGE) { + // Edge + TransferEdgeWData(TopoDS::Edge(myShape),Pts,Cells); + } else { + if(myShape.ShapeType() == TopAbs_VERTEX) { + // Vertex + TransferVertexWData(TopoDS::Vertex(myShape),Pts,Cells); + } + } +} + +//======================================================================= +// Function : TransferFaceWData +// Purpose : Transfert wireframe data for FACE +//======================================================================= + +void GEOM_OCCReader::TransferFaceWData(const TopoDS_Face& aFace, + vtkPoints* Pts, + vtkCellArray* Cells) +{ + TopoDS_Face aCopyFace = aFace; + aCopyFace.Orientation (TopAbs_FORWARD); + createISO(aCopyFace,Precision::Infinite(),1,Pts,Cells); +} + +//======================================================================= +// Function : createISO +// Purpose : Create ISO for Face Wireframe representation +//======================================================================= + +void GEOM_OCCReader::createISO (const TopoDS_Face& TopologicalFace, + const Standard_Real Infinite, + const Standard_Integer NbIsos, + vtkPoints* Pts, + vtkCellArray* Cell) +{ + Geom2dHatch_Hatcher aHatcher (Geom2dHatch_Intersector (IntersectorConfusion, + IntersectorTangency), + HatcherConfusion2d, + HatcherConfusion3d, + Standard_True, + Standard_False); + + Standard_Real myInfinite,myUMin,myUMax,myVMin,myVMax; + //myInfinite = Precision::Infinite(); + myInfinite = 1e38; // VTK uses float numbers - Precision::Infinite() is double and can not be accepted. + + Standard_Integer myNbDom; + TColStd_Array1OfReal myUPrm(1, NbIsos),myVPrm(1, NbIsos); + TColStd_Array1OfInteger myUInd(1, NbIsos),myVInd(1, NbIsos); + + myUInd.Init(0); + myVInd.Init(0); + + //----------------------------------------------------------------------- + // If the Min Max bounds are infinite, there are bounded to Infinite + // value. + //----------------------------------------------------------------------- + + BRepTools::UVBounds (TopologicalFace, myUMin, myUMax, myVMin, myVMax) ; + Standard_Boolean InfiniteUMin = Precision::IsNegativeInfinite (myUMin) ; + Standard_Boolean InfiniteUMax = Precision::IsPositiveInfinite (myUMax) ; + Standard_Boolean InfiniteVMin = Precision::IsNegativeInfinite (myVMin) ; + Standard_Boolean InfiniteVMax = Precision::IsPositiveInfinite (myVMax) ; + if (InfiniteUMin && InfiniteUMax) { + myUMin = - myInfinite ; + myUMax = myInfinite ; + } else if (InfiniteUMin) { + myUMin = myUMax - myInfinite ; + } else if (InfiniteUMax) { + myUMax = myUMin + myInfinite ; + } + if (InfiniteVMin && InfiniteVMax) { + myVMin = - myInfinite ; + myVMax = myInfinite ; + } else if (InfiniteVMin) { + myVMin = myVMax - myInfinite ; + } else if (InfiniteVMax) { + myVMax = myVMin + myInfinite ; + } + + //----------------------------------------------------------------------- + // Retreiving the edges and loading them into the hatcher. + //----------------------------------------------------------------------- + + TopExp_Explorer ExpEdges ; + for (ExpEdges.Init (TopologicalFace, TopAbs_EDGE) ; ExpEdges.More() ; ExpEdges.Next()) { + const TopoDS_Edge& TopologicalEdge = TopoDS::Edge (ExpEdges.Current()) ; + Standard_Real U1, U2 ; + const Handle(Geom2d_Curve) PCurve = BRep_Tool::CurveOnSurface (TopologicalEdge, TopologicalFace, U1, U2) ; + + if ( PCurve.IsNull() ) { + return; + } + + if ( U1==U2) { + return; + } + + //-- Test if a TrimmedCurve is necessary + if( Abs(PCurve->FirstParameter()-U1)<= Precision::PConfusion() + && Abs(PCurve->LastParameter()-U2)<= Precision::PConfusion()) { + aHatcher.AddElement (PCurve, TopologicalEdge.Orientation()) ; + } + else { + if (!PCurve->IsPeriodic()) { + Handle (Geom2d_TrimmedCurve) TrimPCurve =Handle(Geom2d_TrimmedCurve)::DownCast(PCurve); + if (!TrimPCurve.IsNull()) { + if (TrimPCurve->BasisCurve()->FirstParameter()-U1 > Precision::PConfusion() || + U2-TrimPCurve->BasisCurve()->LastParameter() > Precision::PConfusion()) { + aHatcher.AddElement (PCurve, TopologicalEdge.Orientation()) ; + return; + } + } + else { + if (PCurve->FirstParameter()-U1 > Precision::PConfusion()){ + U1=PCurve->FirstParameter(); + } + if (U2-PCurve->LastParameter() > Precision::PConfusion()){ + U2=PCurve->LastParameter(); + } + } + } + Handle (Geom2d_TrimmedCurve) TrimPCurve = new Geom2d_TrimmedCurve (PCurve, U1, U2) ; + aHatcher.AddElement (TrimPCurve, TopologicalEdge.Orientation()) ; + } + } + + + //----------------------------------------------------------------------- + // Loading and trimming the hatchings. + //----------------------------------------------------------------------- + + Standard_Integer IIso ; + Standard_Real DeltaU = Abs (myUMax - myUMin) ; + Standard_Real DeltaV = Abs (myVMax - myVMin) ; + Standard_Real confusion = Min (DeltaU, DeltaV) * HatcherConfusion3d ; + aHatcher.Confusion3d (confusion) ; + + Standard_Real StepU = DeltaU / (Standard_Real) NbIsos ; + if (StepU > confusion) { + Standard_Real UPrm = myUMin + StepU / 2. ; + gp_Dir2d Dir (0., 1.) ; + for (IIso = 1 ; IIso <= NbIsos ; IIso++) { + myUPrm(IIso) = UPrm ; + gp_Pnt2d Ori (UPrm, 0.) ; + Geom2dAdaptor_Curve HCur (new Geom2d_Line (Ori, Dir)) ; + myUInd(IIso) = aHatcher.AddHatching (HCur) ; + UPrm += StepU ; + } + } + + Standard_Real StepV = DeltaV / (Standard_Real) NbIsos ; + if (StepV > confusion) { + Standard_Real VPrm = myVMin + StepV / 2. ; + gp_Dir2d Dir (1., 0.) ; + for (IIso = 1 ; IIso <= NbIsos ; IIso++) { + myVPrm(IIso) = VPrm ; + gp_Pnt2d Ori (0., VPrm) ; + Geom2dAdaptor_Curve HCur (new Geom2d_Line (Ori, Dir)) ; + myVInd(IIso) = aHatcher.AddHatching (HCur) ; + VPrm += StepV ; + } + } + + //----------------------------------------------------------------------- + // Computation. + //----------------------------------------------------------------------- + + aHatcher.Trim() ; + + myNbDom = 0 ; + for (IIso = 1 ; IIso <= NbIsos ; IIso++) { + Standard_Integer Index ; + + Index = myUInd(IIso) ; + if (Index != 0) { + if (aHatcher.TrimDone (Index) && !aHatcher.TrimFailed (Index)) { + aHatcher.ComputeDomains (Index); + if (aHatcher.IsDone (Index)) myNbDom = myNbDom + aHatcher.NbDomains (Index) ; + } + } + + Index = myVInd(IIso) ; + if (Index != 0) { + if (aHatcher.TrimDone (Index) && !aHatcher.TrimFailed (Index)) { + aHatcher.ComputeDomains (Index); + if (aHatcher.IsDone (Index)) myNbDom = myNbDom + aHatcher.NbDomains (Index) ; + } + } + } + + //----------------------------------------------------------------------- + // Push iso lines in vtk kernel + //----------------------------------------------------------------------- + + + Standard_Integer pt_start_idx = 0; + + for (Standard_Integer UIso = myUPrm.Lower() ; UIso <= myUPrm.Upper() ; UIso++) { + Standard_Integer UInd = myUInd.Value (UIso) ; + if (UInd != 0) { + Standard_Real UPrm = myUPrm.Value (UIso) ; + if (!aHatcher.IsDone (UInd)) { + MESSAGE("DBRep_IsoBuilder:: U iso of parameter: "<InsertNextPoint(coord); + +} + +//======================================================================= +// Function : DrawTo +// Purpose : Plot point in VTK +//======================================================================= +void GEOM_OCCReader::DrawTo(gp_Pnt P, + vtkPoints* Pts, + vtkCellArray* Cells) +{ + float coord[3]; + coord[0] = P.X(); coord[1] = P.Y(); coord[2] = P.Z(); + Standard_Integer NewVTKpoint = Pts->InsertNextPoint(coord); + + int pts[2]; + pts[0] = lastVTKpoint; + pts[1] = NewVTKpoint; + + Cells->InsertNextCell(2,pts); + + lastVTKpoint = NewVTKpoint; +} + + +//======================================================================= +// Function : DrawIso +// Purpose : Draw an iso on vtk +//======================================================================= +void GEOM_OCCReader::DrawIso(GeomAbs_IsoType T, + Standard_Real Par, + Standard_Real T1, + Standard_Real T2, + vtkPoints* Pts, + vtkCellArray* Cells, + Standard_Integer& startidx) +{ + + Standard_Boolean halt = Standard_False; + Standard_Integer j,myDiscret = discretiso; + Standard_Real U1,U2,V1,V2,stepU=0.,stepV=0.; + gp_Pnt P; + TopLoc_Location l; + + const Handle(Geom_Surface)& S = BRep_Tool::Surface(TopoDS::Face(myShape),l); + if (!S.IsNull()) { + BRepAdaptor_Surface S(TopoDS::Face(myShape),Standard_False); + + GeomAbs_SurfaceType SurfType = S.GetType(); + + GeomAbs_CurveType CurvType = GeomAbs_OtherCurve; + + Standard_Integer Intrv, nbIntv; + Standard_Integer nbUIntv = S.NbUIntervals(GeomAbs_CN); + Standard_Integer nbVIntv = S.NbVIntervals(GeomAbs_CN); + TColStd_Array1OfReal TI(1,Max(nbUIntv, nbVIntv)+1); + + + if (T == GeomAbs_IsoU) { + S.VIntervals(TI, GeomAbs_CN); + V1 = Max(T1, TI(1)); + V2 = Min(T2, TI(2)); + U1 = Par; + U2 = Par; + stepU = 0; + nbIntv = nbVIntv; + } + else { + S.UIntervals(TI, GeomAbs_CN); + U1 = Max(T1, TI(1)); + U2 = Min(T2, TI(2)); + V1 = Par; + V2 = Par; + stepV = 0; + nbIntv = nbUIntv; + } + + S.D0(U1,V1,P); + MoveTo(P,Pts); + + for (Intrv = 1; Intrv <= nbIntv; Intrv++) { + + if (TI(Intrv) <= T1 && TI(Intrv + 1) <= T1) + continue; + if (TI(Intrv) >= T2 && TI(Intrv + 1) >= T2) + continue; + if (T == GeomAbs_IsoU) { + V1 = Max(T1, TI(Intrv)); + V2 = Min(T2, TI(Intrv + 1)); + stepV = (V2 - V1) / myDiscret; + } + else { + U1 = Max(T1, TI(Intrv)); + U2 = Min(T2, TI(Intrv + 1)); + stepU = (U2 - U1) / myDiscret; + } + + switch (SurfType) { + //-------------GeomAbs_Plane--------------- + case GeomAbs_Plane : + break; + //----GeomAbs_Cylinder GeomAbs_Cone------ + case GeomAbs_Cylinder : + case GeomAbs_Cone : + if (T == GeomAbs_IsoV) { + for (j = 1; j < myDiscret; j++) { + U1 += stepU; + V1 += stepV; + S.D0(U1,V1,P); + DrawTo(P,Pts,Cells); + } + } + break; + //---GeomAbs_Sphere GeomAbs_Torus-------- + //GeomAbs_BezierSurface GeomAbs_BezierSurface + case GeomAbs_Sphere : + case GeomAbs_Torus : + case GeomAbs_OffsetSurface : + case GeomAbs_OtherSurface : + for (j = 1; j < myDiscret; j++) { + U1 += stepU; + V1 += stepV; + S.D0(U1,V1,P); + DrawTo(P,Pts,Cells); + } + break; + //-------------GeomAbs_BSplineSurface------ + case GeomAbs_BezierSurface : + case GeomAbs_BSplineSurface : + for (j = 1; j <= myDiscret/2; j++) { + + PlotCount = 0; + + PlotIso ( S, T, U1, V1, (T == GeomAbs_IsoV) ? stepU*2. : stepV*2., halt, Pts, Cells); + U1 += stepU*2.; + V1 += stepV*2.; + } + break; + //-------------GeomAbs_SurfaceOfExtrusion-- + //-------------GeomAbs_SurfaceOfRevolution- + case GeomAbs_SurfaceOfExtrusion : + case GeomAbs_SurfaceOfRevolution : + if ((T == GeomAbs_IsoV && SurfType == GeomAbs_SurfaceOfRevolution) || + (T == GeomAbs_IsoU && SurfType == GeomAbs_SurfaceOfExtrusion)) { + if (SurfType == GeomAbs_SurfaceOfExtrusion) break; + for (j = 1; j < myDiscret; j++) { + U1 += stepU; + V1 += stepV; + S.D0(U1,V1,P); + DrawTo(P,Pts,Cells); + } + } else { + CurvType = (S.BasisCurve())->GetType(); + switch (CurvType) { + case GeomAbs_Line : + break; + case GeomAbs_Circle : + case GeomAbs_Ellipse : + for (j = 1; j < myDiscret; j++) { + U1 += stepU; + V1 += stepV; + S.D0(U1,V1,P); + DrawTo(P,Pts,Cells); + } + break; + case GeomAbs_Parabola : + case GeomAbs_Hyperbola : + case GeomAbs_BezierCurve : + case GeomAbs_BSplineCurve : + case GeomAbs_OtherCurve : + for (j = 1; j <= myDiscret/2; j++) { + + PlotCount = 0; + + PlotIso ( S, T, U1, V1,(T == GeomAbs_IsoV) ? stepU*2. : stepV*2., halt, Pts, Cells); + U1 += stepU*2.; + V1 += stepV*2.; + } + break; + } + } + } + } + S.D0(U2,V2,P); + DrawTo(P,Pts,Cells); + } +} + +//======================================================================= +// Function : PlotIso +// Purpose : Plot iso for other surface +//======================================================================= + +void GEOM_OCCReader::PlotIso (BRepAdaptor_Surface& S, + GeomAbs_IsoType T, + Standard_Real& U, + Standard_Real& V, + Standard_Real Step, + Standard_Boolean& halt, + vtkPoints* Pts, + vtkCellArray* Cells) +{ + + ++PlotCount; + + gp_Pnt Pl, Pr, Pm; + + if (T == GeomAbs_IsoU) { + S.D0(U, V, Pl); + S.D0(U, V + Step/2., Pm); + S.D0(U, V + Step, Pr); + } else { + S.D0(U, V, Pl); + S.D0(U + Step/2., V, Pm); + S.D0(U + Step, V, Pr); + } + + if (PlotCount > MaxPlotCount) { + DrawTo(Pr,Pts,Cells); + return; + } + + if (Pm.Distance(Pl) + Pm.Distance(Pr) <= IsoRatio*Pl.Distance(Pr)) { + DrawTo(Pr,Pts,Cells); + } else + if (T == GeomAbs_IsoU) { + PlotIso ( S, T, U, V, Step/2, halt, Pts, Cells); + Standard_Real aLocalV = V + Step/2 ; + PlotIso ( S, T, U, aLocalV , Step/2, halt, Pts, Cells); + } else { + PlotIso ( S, T, U, V, Step/2, halt, Pts, Cells); + Standard_Real aLocalU = U + Step/2 ; + PlotIso ( S, T, aLocalU , V, Step/2, halt, Pts, Cells); + } +} + +//======================================================================= +// Function : TransferEdgeWData +// Purpose : Transfert wireframe data for EDGE +//======================================================================= + +void GEOM_OCCReader::TransferEdgeWData(const TopoDS_Edge& aEdge, + vtkPoints* Pts, + vtkCellArray* Cells) { + + + Handle(Poly_PolygonOnTriangulation) aEdgePoly; + Standard_Integer i = 1; + Handle(Poly_Triangulation) T; + TopLoc_Location aEdgeLoc; + BRep_Tool::PolygonOnTriangulation(aEdge, aEdgePoly, T, aEdgeLoc, i); + + Handle(Poly_Polygon3D) P; + if(aEdgePoly.IsNull()) { + P = BRep_Tool::Polygon3D(aEdge, aEdgeLoc); + } + + if(P.IsNull() && aEdgePoly.IsNull()) + return; + + // Location edges + //--------------- + + gp_Trsf edgeTransf; + Standard_Boolean isidtrsf = true; + if(!aEdgeLoc.IsIdentity()) { + isidtrsf = false; + edgeTransf = aEdgeLoc.Transformation(); + } + + Standard_Integer nbnodes; + if (aEdgePoly.IsNull()) { + nbnodes = P->NbNodes(); + const TColgp_Array1OfPnt& theNodesP = P->Nodes(); + + float coord[3]; + int pts[2]; + + for(int j=1;jInsertNextPoint(coord); + + // insert pt2 + coord[0] = pt2.X(); coord[1] = pt2.Y(); coord[2] = pt2.Z(); + pts[1] = Pts->InsertNextPoint(coord); + + // insert line (pt1,pt2) + Cells->InsertNextCell(2,pts); + } + } else { + nbnodes = aEdgePoly->NbNodes(); + const TColStd_Array1OfInteger& Nodesidx = aEdgePoly->Nodes(); + const TColgp_Array1OfPnt& theNodesPoly = T->Nodes(); + + float coord[3]; + int pts[2]; + + for(int j=1;jInsertNextPoint(coord); + + // insert pt2 + coord[0] = pt2.X(); coord[1] = pt2.Y(); coord[2] = pt2.Z(); + pts[1] = Pts->InsertNextPoint(coord); + + // insert line (pt1,pt2) + Cells->InsertNextCell(2,pts); + } + } +} + +/* Standard_Integer nbnodes = aEdgePoly->NbNodes(); + const TColStd_Array1OfInteger& Nodesidx = aEdgePoly->Nodes(); + const TColgp_Array1OfPnt& theNodes = T->Nodes(); + + float coord[3]; + int pts[2]; + + + // PUSH NODES + for(i=1;i<=nbnodes;i++) { + Standard_Integer id = Nodesidx(i); + gp_Pnt pt = theNodes(id); + + float coord[3]; + if(!isidtrsf) pt.Transform(edgeTransf); + + coord[0] = pt.X(); coord[1] = pt.Y(); coord[2] = pt.Z(); + + Pts->SetPoint(id-1,coord); + + } + + // PUSH EDGES + for(i=1;iInsertNextCell(2,pts); + } + + + }*/ + +//======================================================================= +// Function : TransferVertexWData +// Purpose : Transfert wireframe data for VERTEX +//======================================================================= + +void GEOM_OCCReader::TransferVertexWData(const TopoDS_Vertex& aVertex, + vtkPoints* Pts, + vtkCellArray* Cells) { +#define ZERO_COORD coord[0] = 0.0; coord[1] = 0.0; coord[2] = 0.0 + + gp_Pnt P = BRep_Tool::Pnt( aVertex ); + float delta = 1, coord[3]; + int pts[2]; + // insert pt + ZERO_COORD; coord[0] = +delta; + pts[0] = Pts->InsertNextPoint(coord); + coord[0] = -delta; + pts[1] = Pts->InsertNextPoint(coord); + // insert line (pt1,pt2) + Cells->InsertNextCell(2,pts); + + ZERO_COORD; coord[1] = +delta; + pts[0] = Pts->InsertNextPoint(coord); + coord[1] = -delta; + pts[1] = Pts->InsertNextPoint(coord); + // insert line (pt1,pt2) + Cells->InsertNextCell(2,pts); + + ZERO_COORD; coord[2] = +delta; + pts[0] = Pts->InsertNextPoint(coord); + coord[2] = -delta; + pts[1] = Pts->InsertNextPoint(coord); + // insert line (pt1,pt2) + Cells->InsertNextCell(2,pts); + +#undef ZERO_COORD +} + +//======================================================================= +// Function : TransferEdgeSData( +// Purpose : Transfert shading data for EDGE +//======================================================================= + +void GEOM_OCCReader::TransferEdgeSData(const TopoDS_Edge& aFace, + vtkPoints* Pts, + vtkCellArray* Cells) +{ +} + + +//======================================================================= +// Function : TransferFaceSData +// Purpose : Transfert shading data for FACE +//======================================================================= +void GEOM_OCCReader::TransferFaceSData(const TopoDS_Face& aFace, + vtkPoints* Pts, + vtkCellArray* Cells) { + + TopLoc_Location aLoc; + Handle(Poly_Triangulation) aPoly = BRep_Tool::Triangulation(aFace,aLoc); + if(aPoly.IsNull()) return; + else { + + gp_Trsf myTransf; + Standard_Boolean identity = true; + if(!aLoc.IsIdentity()) { + identity = false; + myTransf = aLoc.Transformation(); + } + + Standard_Integer nbNodesInFace = aPoly->NbNodes(); + Standard_Integer nbTriInFace = aPoly->NbTriangles(); + + const Poly_Array1OfTriangle& Triangles = aPoly->Triangles(); + const TColgp_Array1OfPnt& Nodes = aPoly->Nodes(); + + Standard_Integer i; + for(i=1;i<=nbNodesInFace;i++) { + gp_Pnt P = Nodes(i); + float coord[3]; + if(!identity) P.Transform(myTransf); + coord[0] = P.X(); coord[1] = P.Y(); coord[2] = P.Z(); + Pts->SetPoint(i-1,coord); + } + + for(i=1;i<=nbTriInFace;i++) { + // Get the triangle + + Standard_Integer N1,N2,N3; + Triangles(i).Get(N1,N2,N3); + + int pts[3]; + pts[0] = N1-1; pts[1] = N2-1; pts[2] = N3-1; + Cells->InsertNextCell(3,pts); + + } + } +} + +//======================================================================= +// Function : ComputeShading +// Purpose : Compute the shape in shading mode +//======================================================================= +void GEOM_OCCReader::ComputeShading(vtkPoints* Pts,vtkCellArray* Cells){ + + // Check the type of the shape: + if(myShape.ShapeType() == TopAbs_FACE) { + // Face + TransferFaceSData(TopoDS::Face(myShape),Pts,Cells); + } + else { + if(myShape.ShapeType() == TopAbs_EDGE) { + // Edge + TransferEdgeSData(TopoDS::Edge(myShape),Pts,Cells); + } + else { + } + + } + +} + +//======================================================================= +// Function : +// Purpose : Set parameters +//======================================================================= +void GEOM_OCCReader::setDisplayMode(int thenewmode) { + amode = thenewmode; +} + +void GEOM_OCCReader::setTopo(const TopoDS_Shape& aShape) { + myShape = aShape; +} + +void GEOM_OCCReader::setForceUpdate(Standard_Boolean bol) { + forced = bol; +} + +//======================================================================= +// Function : +// Purpose : Get parameters +//======================================================================= +const TopoDS_Shape& GEOM_OCCReader::getTopo() { + return myShape; +} + +int GEOM_OCCReader::getDisplayMode() { + return amode; +} + + diff --git a/OBJECT/GEOM_OCCReader.h b/OBJECT/GEOM_OCCReader.h new file mode 100644 index 000000000..87247f3ec --- /dev/null +++ b/OBJECT/GEOM_OCCReader.h @@ -0,0 +1,140 @@ +// GEOM OBJECT : interactive object for Geometry entities visualization +// +// 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 +// +// +// +// File : GEOM_OCCReader.h +// Author : Christophe ATTANASIO +// Module : GEOM +// $Header$ + +/*! + \class GEOM_OCCReader GEOM_OCCReader.h + \brief This class allow to display a OpenCASCADE CAD model in a VTK viewer. +*/ + +#ifndef GEOM_OCCREADER_H +#define GEOM_OCCREADER_H + +// VTK +#include "VTKViewer_Common.h" + +// OpenCASCADE +#include +#include +#include +#include +#include +#include + +#ifdef _WIN_32 +#define VTKOCC_EXPORT __declspec (dllexport) +#else +#define VTKOCC_EXPORT +#endif +class VTKOCC_EXPORT GEOM_OCCReader : public vtkPolyDataSource { + + // methods + + public: + + static GEOM_OCCReader* New(); + + const TopoDS_Shape& getTopo(); + + void setTopo(const TopoDS_Shape& ashape); + + int getDisplayMode(); + void setDisplayMode(int); + + void setForceUpdate(Standard_Boolean bol); + + protected: + + GEOM_OCCReader(); + ~GEOM_OCCReader(); + void Execute(); + + void ComputeShading(vtkPoints* Pts,vtkCellArray* Cells); + void ComputeWireframe(vtkPoints* Pts,vtkCellArray* Cells); + + void TransferFaceSData(const TopoDS_Face& aFace, + vtkPoints* Pts, + vtkCellArray* Cells); + + void TransferFaceWData(const TopoDS_Face& aFace, + vtkPoints* Pts, + vtkCellArray* Cells); + + void TransferEdgeSData(const TopoDS_Edge& aEdge, + vtkPoints* Pts, + vtkCellArray* Cells); + + void TransferEdgeWData(const TopoDS_Edge& aEdge, + vtkPoints* Pts, + vtkCellArray* Cells); + + void TransferVertexWData(const TopoDS_Vertex& aVertex, + vtkPoints* Pts, + vtkCellArray* Cells); + + void createISO(const TopoDS_Face &, + double, int, + vtkPoints* Pts, + vtkCellArray* Cells); + + void DrawIso(GeomAbs_IsoType aType, + Standard_Real PParm, + Standard_Real p1, + Standard_Real p2, + vtkPoints* Pts, + vtkCellArray* Cells, + Standard_Integer& startidx); + + void MoveTo(gp_Pnt P, + vtkPoints* Pts); + + void DrawTo(gp_Pnt P, + vtkPoints* Pts, + vtkCellArray* Cells); + + void PlotIso(BRepAdaptor_Surface& S, + GeomAbs_IsoType T, + Standard_Real& U, + Standard_Real& V, + Standard_Real Step, + Standard_Boolean& halt, + vtkPoints* Pts, + vtkCellArray* Cells); + + // fields + + private: + + Standard_Boolean forced; + int discretiso; + int amode; + int nbisos; + TopoDS_Shape myShape; + +}; + +#endif //GEOM_OCCREADER_H diff --git a/OBJECT/Handle_GEOM_AISShape.hxx b/OBJECT/Handle_GEOM_AISShape.hxx new file mode 100644 index 000000000..af8efe053 --- /dev/null +++ b/OBJECT/Handle_GEOM_AISShape.hxx @@ -0,0 +1,100 @@ +// GEOM OBJECT : interactive object for Geometry entities visualization +// +// 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 +// +// +// +// File : Handle_GEOM_AISShape.hxx +// Module : GEOM + +#ifndef _Handle_GEOM_AISShape_HeaderFile +#define _Handle_GEOM_AISShape_HeaderFile + +#ifndef _Standard_Macro_HeaderFile +#include +#endif +#ifndef _Standard_HeaderFile +#include +#endif + +#ifndef _Handle_SALOME_AISShape_HeaderFile +#include "Handle_SALOME_AISShape.hxx" +#endif + +class Standard_Transient; +class Handle_Standard_Type; +class Handle(SALOME_AISShape); +class GEOM_AISShape; +Standard_EXPORT Handle_Standard_Type& STANDARD_TYPE(GEOM_AISShape); + +class Handle(GEOM_AISShape) : public Handle(SALOME_AISShape) { + public: + inline void* operator new(size_t,void* anAddress) + { + return anAddress; + } + inline void* operator new(size_t size) + { + return Standard::Allocate(size); + } + inline void operator delete(void *anAddress) + { + if (anAddress) Standard::Free((Standard_Address&)anAddress); + } +// inline void operator delete(void *anAddress, size_t size) +// { +// if (anAddress) Standard::Free((Standard_Address&)anAddress,size); +// } + Handle(GEOM_AISShape)():Handle(SALOME_AISShape)() {} + Handle(GEOM_AISShape)(const Handle(GEOM_AISShape)& aHandle) : Handle(SALOME_AISShape)(aHandle) + { + } + + Handle(GEOM_AISShape)(const GEOM_AISShape* anItem) : Handle(SALOME_AISShape)((SALOME_AISShape *)anItem) + { + } + + Handle(GEOM_AISShape)& operator=(const Handle(GEOM_AISShape)& aHandle) + { + Assign(aHandle.Access()); + return *this; + } + + Handle(GEOM_AISShape)& operator=(const GEOM_AISShape* anItem) + { + Assign((Standard_Transient *)anItem); + return *this; + } + + GEOM_AISShape* operator->() + { + return (GEOM_AISShape *)ControlAccess(); + } + + GEOM_AISShape* operator->() const + { + return (GEOM_AISShape *)ControlAccess(); + } + + Standard_EXPORT ~Handle(GEOM_AISShape)(); + + Standard_EXPORT static const Handle(GEOM_AISShape) DownCast(const Handle(Standard_Transient)& AnObject); +}; +#endif diff --git a/OBJECT/Handle_GEOM_InteractiveObject.hxx b/OBJECT/Handle_GEOM_InteractiveObject.hxx new file mode 100644 index 000000000..63c0e8e3f --- /dev/null +++ b/OBJECT/Handle_GEOM_InteractiveObject.hxx @@ -0,0 +1,100 @@ +// GEOM OBJECT : interactive object for Geometry entities visualization +// +// 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 +// +// +// +// File : Handle_GEOM_InteractiveObject.hxx +// Module : GEOM + +#ifndef _Handle_GEOM_InteractiveObject_HeaderFile +#define _Handle_GEOM_InteractiveObject_HeaderFile + +#ifndef _Standard_Macro_HeaderFile +#include +#endif +#ifndef _Standard_HeaderFile +#include +#endif + +#ifndef _Handle_SALOME_InteractiveObject_HeaderFile +#include "Handle_SALOME_InteractiveObject.hxx" +#endif + +class Standard_Transient; +class Handle_Standard_Type; +class Handle(SALOME_InteractiveObject); +class GEOM_InteractiveObject; +Standard_EXPORT Handle_Standard_Type& STANDARD_TYPE(GEOM_InteractiveObject); + +class Handle(GEOM_InteractiveObject) : public Handle(SALOME_InteractiveObject) { + public: + inline void* operator new(size_t,void* anAddress) + { + return anAddress; + } + inline void* operator new(size_t size) + { + return Standard::Allocate(size); + } + inline void operator delete(void *anAddress) + { + if (anAddress) Standard::Free((Standard_Address&)anAddress); + } +// inline void operator delete(void *anAddress, size_t size) +// { +// if (anAddress) Standard::Free((Standard_Address&)anAddress,size); +// } + Handle(GEOM_InteractiveObject)():Handle(SALOME_InteractiveObject)() {} + Handle(GEOM_InteractiveObject)(const Handle(GEOM_InteractiveObject)& aHandle) : Handle(SALOME_InteractiveObject)(aHandle) + { + } + + Handle(GEOM_InteractiveObject)(const GEOM_InteractiveObject* anItem) : Handle(SALOME_InteractiveObject)((SALOME_InteractiveObject *)anItem) + { + } + + Handle(GEOM_InteractiveObject)& operator=(const Handle(GEOM_InteractiveObject)& aHandle) + { + Assign(aHandle.Access()); + return *this; + } + + Handle(GEOM_InteractiveObject)& operator=(const GEOM_InteractiveObject* anItem) + { + Assign((Standard_Transient *)anItem); + return *this; + } + + GEOM_InteractiveObject* operator->() + { + return (GEOM_InteractiveObject *)ControlAccess(); + } + + GEOM_InteractiveObject* operator->() const + { + return (GEOM_InteractiveObject *)ControlAccess(); + } + + Standard_EXPORT ~Handle(GEOM_InteractiveObject)(); + + Standard_EXPORT static const Handle(GEOM_InteractiveObject) DownCast(const Handle(Standard_Transient)& AnObject); +}; +#endif diff --git a/OBJECT/Makefile.in b/OBJECT/Makefile.in new file mode 100644 index 000000000..8c03ab723 --- /dev/null +++ b/OBJECT/Makefile.in @@ -0,0 +1,65 @@ +# GEOM OBJECT : interactive object for Geometry entities visualization +# +# 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 +# +# +# +# File : Makefile.in +# Module : GEOM + +top_srcdir=@top_srcdir@ +top_builddir=../../.. +srcdir=@srcdir@ +VPATH=.:@srcdir@:@top_srcdir@/idl + + +@COMMENCE@ + +EXPORT_HEADERS = GEOM_Actor.h \ + GEOM_AssemblyBuilder.h \ + GEOM_AISShape.hxx \ + Handle_GEOM_AISShape.hxx \ + GEOM_InteractiveObject.hxx \ + Handle_GEOM_InteractiveObject.hxx + + +# Libraries targets + +LIB = libGeometryObject.la +LIB_SRC = GEOM_Actor.cxx \ + GEOM_OCCReader.cxx \ + GEOM_AssemblyBuilder.cxx \ + GEOM_AISShape.cxx \ + GEOM_InteractiveObject.cxx + +LIB_CLIENT_IDL = + +# Executables targets +BIN = +BIN_SRC = + +CPPFLAGS+=$(QT_INCLUDES) $(PYTHON_INCLUDES) $(OCC_INCLUDES) $(VTK_INCLUDES) $(OGL_INCLUDES) +LDFLAGS+=$(QT_MT_LIBS) $(OCC_LIBS) $(VTK_LIBS) $(OGL_LIBS) $(PYTHON_LIBS) -lSalomeObject + +%_moc.cxx: %.h + $(MOC) $< -o $@ + + +@CONCLUDE@ diff --git a/PARTITION/Makefile.in b/PARTITION/Makefile.in new file mode 100644 index 000000000..98694a9d2 --- /dev/null +++ b/PARTITION/Makefile.in @@ -0,0 +1,63 @@ +# 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 +# +# +# +# File : Makefile.in +# Author : Marc Tajchman (CEA) +# Module : GEOM +# $Header$ + +top_srcdir=@top_srcdir@ +top_builddir=../../.. +srcdir=@srcdir@ +VPATH=.:@srcdir@ + + +@COMMENCE@ + +# Libraries targets +LIB = libGeometryPartition.la +LIB_SRC = Partition_Inter2d.cxx \ + Partition_Inter3d.cxx \ + Partition_Loop2d.cxx \ + Partition_Loop3d.cxx \ + Partition_Spliter.cxx + +LIB_CLIENT_IDL = +LIB_SERVER_IDL = + +# header files +EXPORT_HEADERS = Partition_Spliter.hxx \ + Partition_Inter3d.hxx + +# idl files +EXPORT_IDLS= + + +CPPFLAGS += $(OCC_INCLUDES) +CXXFLAGS += $(OCC_CXXFLAGS) +LDFLAGS += $(OCC_LIBS) + +%_moc.cxx: %.h + $(MOC) $< -o $@ + +@CONCLUDE@ diff --git a/PARTITION/Partition.cdl b/PARTITION/Partition.cdl new file mode 100644 index 000000000..9b1bf2287 --- /dev/null +++ b/PARTITION/Partition.cdl @@ -0,0 +1,44 @@ +-- 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 +-- +-- +-- +-- File : Partition.cdl +-- Author : Benedicte MARTIN +-- Module : GEOM + +package Partition + +uses + TopoDS, + TopTools, + TopAbs, + BRepAlgo, + BRep, + gp +is + class Spliter; + class Inter3d; + class Inter2d; + class Loop2d; + class Loop3d; + +end Partition; diff --git a/PARTITION/Partition_Inter2d.cdl b/PARTITION/Partition_Inter2d.cdl new file mode 100644 index 000000000..a3a4d15d2 --- /dev/null +++ b/PARTITION/Partition_Inter2d.cdl @@ -0,0 +1,74 @@ +-- 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 +-- +-- +-- +-- File : Partition_Inter2d.cdl +-- Author : Benedicte MARTIN +-- Module : GEOM + +class Inter2d from Partition + + ---Purpose: Computes the intersections between edges on a face + -- stores result is SD as AsDes from BRepAlgo. + +uses + AsDes from BRepAlgo, + Edge from TopoDS, + Face from TopoDS, + Vertex from TopoDS, + MapOfShape from TopTools, + Real from Standard, + ListOfShape from TopTools + +is + CompletPart2d(myclass ; AsDes : mutable AsDes from BRepAlgo; + F : Face from TopoDS; + NewEdges : MapOfShape from TopTools); + + ---Purpose: Computes the intersections between the edges stored + -- is AsDes as descendants of . Intersections is computed + -- between two edges if one of them is bound in NewEdges. + + + FindEndVertex(myclass; VertList : ListOfShape from TopTools; + f,l : Real from Standard; + E : Edge from TopoDS; + First : out Boolean from Standard; + DU : out Real from Standard) + returns Vertex from TopoDS; + ---Purpose: Returns a vertex from having parameter on + -- most close to or . is True if + -- found vertex is closer to . returns parameter + -- difference. + + AddVonE(myclass; V : Vertex from TopoDS; + E1,E2 : Edge from TopoDS; + AsDes : mutable AsDes from BRepAlgo) + 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. + +end Inter2d; + diff --git a/PARTITION/Partition_Inter2d.cxx b/PARTITION/Partition_Inter2d.cxx new file mode 100644 index 000000000..e15bf24e3 --- /dev/null +++ b/PARTITION/Partition_Inter2d.cxx @@ -0,0 +1,545 @@ +// 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 +// +// +// +// File : Partition_Inter2d.cxx +// Author : Benedicte MARTIN +// Module : GEOM +// $Header$ + +using namespace std; +#include "Partition_Inter2d.ixx" + +#include "utilities.h" + +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef DEB +static Standard_Boolean TestEdges = 0; +static Standard_Integer NbF2d = 0; +static Standard_Integer NbE2d = 0; +#endif + +//======================================================================= +//function : StorePart2d +//purpose : +//======================================================================= + +// 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) + +{ + //------------------------------------------------------------- + // test if the points of intersection already exist. If not, + // add as descendants of the edges. + // nb: theses points are only vertices of intersection. + //------------------------------------------------------------- + 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; + 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; + + //----------------------------------------------------------------- + // 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 vertex found is still on E2. + //----------------------------------------------------------------- + for (it.Initialize(VOnE2); it.More(); it.Next()) { + if (V.IsSame( it.Value() )) { + OnE2 = Standard_True; + V2 = V; + 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) { + 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); + } + } + // 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); + } + if (!OnE2) { + if (OnE1) { + V.Orientation(TopAbs_INTERNAL); + B.UpdateVertex(V,U2,E2, Tol1); + } + V.Orientation(O2); + NewVOnE2.Prepend(V); + } +// } + + if (!NewVOnE1.IsEmpty()) AsDes->Add(E1,NewVOnE1); + if (!NewVOnE2.IsEmpty()) AsDes->Add(E2,NewVOnE2); + + return V; +} + +//======================================================================= +//function : FindEndVertex +//purpose : Returns a vertex from having parameter on +// closest to or . is True if +// found vertex is closer to . returns parameter +// difference. +//======================================================================= + +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) +{ + TopoDS_Vertex endV; + Standard_Real U, endU, min; + minDU = 1.e10; + + TopTools_ListIteratorOfListOfShape it; + it.Initialize(LV); + for (; it.More(); it.Next()) { + const TopoDS_Vertex& v = TopoDS::Vertex(it.Value()); + U = BRep_Tool::Parameter(v, E); + min = Min( Abs(U-f), Abs(U-l) ); + if (min < minDU) { + endV = v; + endU = U; + minDU = min; + } + } + if (Abs(endU-f) < Abs(endU-l)) + isFirst = Standard_True; + else + isFirst = Standard_False; + + return endV; +} + +//======================================================================= +//function : treatClosed +//purpose : add second vertex to closed edge. Vertex is one of +//======================================================================= + +static void treatClosed (const TopoDS_Edge& E1, + const Standard_Real f, + const Standard_Real l, + TopTools_ListOfShape& LV1, + TopTools_ListOfShape& /*LV2*/) +{ + Standard_Boolean isFirst=0; + Standard_Real minDU = 1.e10; + TopoDS_Vertex endV; + endV = Partition_Inter2d::FindEndVertex(LV1, f,l, E1, isFirst,minDU); + + if (minDU > Precision::PConfusion()) + return; // not end point + + Standard_Real newU; + if (isFirst) + newU = f + (l - f); + else + newU = l - (l - f); + + // update end parameter + BRep_Builder B; + endV.Orientation(TopAbs_INTERNAL); + B.UpdateVertex(endV,newU,E1,BRep_Tool::Tolerance(endV)); +} + +//======================================================================= +//function : EdgesPartition +//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) +{ + + Standard_Real f[3],l[3]; + Standard_Real MilTol2; + Standard_Real Tol = Max (BRep_Tool::Tolerance(E1), + BRep_Tool::Tolerance(E2)); + MilTol2 = Tol * Tol * 10; + + BRep_Tool::Range(E1, f[1], l[1]); + BRep_Tool::Range(E2, f[2], l[2]); + + BRepAdaptor_Curve CE1(E1,F); + BRepAdaptor_Curve CE2(E2,F); + + TopoDS_Edge EI[3]; EI[1] = E1; EI[2] = E2; + TopTools_ListOfShape LV1; // new vertices at intersections on E1 + TopTools_ListOfShape LV2; // ... on E2 + BRep_Builder B; + + // if E1 and E2 are results of intersection of F and two connex faces then + // no need to intersect edges, they can contact by vertices only + // (encounted an exception in TopOpeBRep_EdgesIntersector in such a case) + Standard_Boolean intersect = Standard_True; + TopTools_IndexedMapOfShape ME; + TopExp::MapShapes(F, TopAbs_EDGE, ME); + if (!ME.Contains(E1) && ! ME.Contains(E2)) { // if E1 and E2 are new on F + TopoDS_Shape F1, F2; + const TopTools_ListOfShape& LF1 = AsDes->Ascendant( E1 ); + F1 = F.IsSame( LF1.First() ) ? LF1.Last() : LF1.First(); + const TopTools_ListOfShape& LF2 = AsDes->Ascendant( E2 ); + F2 = F.IsSame( LF2.First() ) ? LF2.Last() : LF2.First(); + if (!F.IsSame(F2) && !F.IsSame(F1) ) { + 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 (intersect) { + //------------------------------------------------------ + // compute the points of Intersection in 2D + //----------------------------------------------------- + // i.e. fill LV1 and LV2 + TopOpeBRep_EdgesIntersector EInter; + EInter.SetFaces(F,F); + Standard_Real TolDub = 1.e-7; + EInter.ForceTolerances(TolDub,TolDub); + Standard_Boolean reducesegments = Standard_False; + EInter.Perform (E1,E2,reducesegments); + + Standard_Boolean rejectreducedsegmentpoints = Standard_False; + EInter.InitPoint(rejectreducedsegmentpoints); + for (;EInter.MorePoint();EInter.NextPoint()) { + const TopOpeBRep_Point2d& P2D = EInter.Point(); + const gp_Pnt& P = P2D.Value(); + TopoDS_Vertex V = BRepLib_MakeVertex(P); + + //------------------------- + // control the point found. + //------------------------- + gp_Pnt P1 = CE1.Value(P2D.Parameter(1)); + 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_"< 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); + else LV2.Append(V); + } + } + } + } // if (intersect) + + //---------------------------------- + // Test the extremities of the edges. + //---------------------------------- + // add to LV* vertices for vertex-vertex closeness + Standard_Real U1,U2; + Standard_Real TolConf2, TolConf; + TopoDS_Vertex V1[2],V2[2]; + TopExp::Vertices(E1,V1[0],V1[1]); + TopExp::Vertices(E2,V2[0],V2[1]); + + Standard_Integer i,j,k; + for (j = 0; j < 2; j++) { + if (V1[j].IsNull()) continue; + for ( k = 0; k < 2; k++) { + if (V2[k].IsNull()) continue; + gp_Pnt P1 = BRep_Tool::Pnt(V1[j]); + gp_Pnt P2 = BRep_Tool::Pnt(V2[k]); + TolConf = BRep_Tool::Tolerance(V1[j]) + BRep_Tool::Tolerance(V2[k]); + TolConf = Max (Tol, TolConf); + TolConf2 = TolConf * TolConf; + if (!intersect) + TolConf2 *= 100; + Standard_Real SqDist = P1.SquareDistance(P2); + + if (SqDist <= TolConf2) { + TopoDS_Vertex V = BRepLib_MakeVertex(P1); + V.Orientation(TopAbs_INTERNAL); + U1 = (j == 0) ? f[1] : l[1]; + U2 = (k == 0) ? f[2] : l[2]; + B.UpdateVertex(V,U1,E1,TolConf); + B.UpdateVertex(V,U2,E2,TolConf); + LV1.Prepend(V.Oriented(V1[j].Orientation())); + LV2.Prepend(V.Oriented(V2[k].Orientation())); + } + } + } + + Standard_Boolean AffichPurge = Standard_False; + + if ( LV1.IsEmpty()) return; + + //---------------------------------- + // Purge of all the vertices. + //---------------------------------- + // remove one of close vertices + TopTools_ListIteratorOfListOfShape it1LV1,it1LV2,it2LV1; + gp_Pnt P1,P2; + Standard_Boolean Purge = Standard_True; + + while (Purge) { + i = 1; + Purge = Standard_False; + for (it1LV1.Initialize(LV1),it1LV2.Initialize(LV2); + 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 ); + 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(); + } + if (Purge) break; + i++; + } + } + + // 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); + if (V2[0].IsSame( V2[1] ) && NewEdges.Contains(E2) ) + 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); +} + +//======================================================================= +//function : CompletPart2d +//purpose : Computes the intersections between the edges stored +// is AsDes as descendants of . Intersections is computed +// between two edges if one of them is bound in NewEdges. +//======================================================================= + +void Partition_Inter2d::CompletPart2d (const Handle(BRepAlgo_AsDes)& AsDes, + const TopoDS_Face& F, + const TopTools_MapOfShape& NewEdges) +{ + +#ifdef DEB + NbF2d++; + NbE2d = 0; +#endif + + //Do not intersect the edges of a face + TopTools_IndexedMapOfShape EdgesOfFace; + TopExp::MapShapes( F, TopAbs_EDGE , EdgesOfFace); + + //------------------------------------------------------------------- + // compute the intersection2D on the faces touched by the intersection3D + //------------------------------------------------------------------- + TopTools_ListIteratorOfListOfShape it1LE ; + TopTools_ListIteratorOfListOfShape it2LE ; + + //----------------------------------------------- + // Intersection edge-edge. + //----------------------------------------------- + const TopTools_ListOfShape& LE = AsDes->Descendant(F); + TopoDS_Vertex V1,V2; + Standard_Integer j, i = 1; + + TopoDS_Face FF = F; + FF.Orientation(TopAbs_FORWARD); + + for ( it1LE.Initialize(LE) ; it1LE.More(); it1LE.Next()) { + const TopoDS_Edge& E1 = TopoDS::Edge(it1LE.Value()); + j = 1; + it2LE.Initialize(LE); + + while (j < i && it2LE.More()) { + const TopoDS_Edge& E2 = TopoDS::Edge(it2LE.Value()); + //---------------------------------------------------------- + // Intersections of the new edges obtained by intersection + // 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); + } + it2LE.Next(); + j++; + } + i++; + } +} + diff --git a/PARTITION/Partition_Inter2d.hxx b/PARTITION/Partition_Inter2d.hxx new file mode 100644 index 000000000..7d82aa34b --- /dev/null +++ b/PARTITION/Partition_Inter2d.hxx @@ -0,0 +1,110 @@ +// 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 +// +// +// +// File : Partition_Inter2d.hxx +// Module : GEOM + +#ifndef _Partition_Inter2d_HeaderFile +#define _Partition_Inter2d_HeaderFile + +#ifndef _Handle_BRepAlgo_AsDes_HeaderFile +#include +#endif +#ifndef _Standard_Real_HeaderFile +#include +#endif +#ifndef _Standard_Boolean_HeaderFile +#include +#endif +class BRepAlgo_AsDes; +class TopoDS_Face; +class TopTools_MapOfShape; +class TopoDS_Vertex; +class TopTools_ListOfShape; +class TopoDS_Edge; + + +#ifndef _Standard_HeaderFile +#include +#endif +#ifndef _Standard_Macro_HeaderFile +#include +#endif + +class Partition_Inter2d { + +public: + + void* operator new(size_t,void* anAddress) + { + return anAddress; + } + void* operator new(size_t size) + { + return Standard::Allocate(size); + } + void operator delete(void *anAddress) + { + if (anAddress) Standard::Free((Standard_Address&)anAddress); + } + // Methods 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) ; + + + + + +protected: + + // Methods PROTECTED + // + + + // Fields PROTECTED + // + + +private: + + // Methods PRIVATE + // + + + // Fields PRIVATE + // + + +}; + + + + + +// other Inline functions and methods (like "C++: function call" methods) +// + + +#endif diff --git a/PARTITION/Partition_Inter2d.ixx b/PARTITION/Partition_Inter2d.ixx new file mode 100644 index 000000000..963d1ec17 --- /dev/null +++ b/PARTITION/Partition_Inter2d.ixx @@ -0,0 +1,31 @@ +// 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 +// +// +// +// File : Partition_Inter2d.ixx +// Module : GEOM + +#include "Partition_Inter2d.jxx" + + + + diff --git a/PARTITION/Partition_Inter2d.jxx b/PARTITION/Partition_Inter2d.jxx new file mode 100644 index 000000000..8c3ef7d49 --- /dev/null +++ b/PARTITION/Partition_Inter2d.jxx @@ -0,0 +1,47 @@ +// 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 +// +// +// +// File : Partition_Inter2d.jxx +// Module : GEOM + +#ifndef _BRepAlgo_AsDes_HeaderFile +#include +#endif +#ifndef _TopoDS_Face_HeaderFile +#include +#endif +#ifndef _TopTools_MapOfShape_HeaderFile +#include +#endif +#ifndef _TopoDS_Vertex_HeaderFile +#include +#endif +#ifndef _TopTools_ListOfShape_HeaderFile +#include +#endif +#ifndef _TopoDS_Edge_HeaderFile +#include +#endif +#ifndef _Partition_Inter2d_HeaderFile +#include "Partition_Inter2d.hxx" +#endif diff --git a/PARTITION/Partition_Inter3d.cdl b/PARTITION/Partition_Inter3d.cdl new file mode 100644 index 000000000..38c504aee --- /dev/null +++ b/PARTITION/Partition_Inter3d.cdl @@ -0,0 +1,168 @@ +-- 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 +-- +-- +-- +-- File : Partition_Inter3d.cdl +-- Author : Benedicte MARTIN +-- Module : GEOM + +class Inter3d from Partition + + ---Purpose: Computes the intersection face face in a set of faces + -- Store the result in a SD as AsDes. + +uses + Edge from TopoDS, + Vertex from TopoDS, + DataMapOfShapeShape from TopTools, + MapOfShape from TopTools, + Boolean from Standard, + AsDes from BRepAlgo, + Image from BRepAlgo, + Shape from TopoDS, + Face from TopoDS, + ListOfShape from TopTools, + Real from Standard, + State from TopAbs, + DataMapOfShapeListOfShape from TopTools + +is + Create returns Inter3d from Partition; + + Create(AsDes : mutable AsDes from BRepAlgo); + + CompletPart3d (me : in out; SetOfFaces1 : ListOfShape from TopTools; + FaceShapeMap: DataMapOfShapeShape from TopTools) + is static; + + FacesPartition (me : in out; F1, F2 : Face from TopoDS) + is static; + + ---------------------------- + ---Category: Result Querying + ---------------------------- + + IsDone(me ; F1,F2 : Face from TopoDS) + returns Boolean from Standard is static; + ---Purpose: return True if F1-F2 pair has been processed + + TouchedFaces(me : in out) returns MapOfShape from TopTools + ---C++: return & + is static; + ---Purpose: return map of + + AsDes(me) returns AsDes from BRepAlgo + is static; + + NewEdges(me : in out) returns MapOfShape from TopTools + ---C++: return & + is static; + + ------------------------------- + ---Category: Same domain shapes + ------------------------------- + + HasSameDomainF(me; F : Shape from TopoDS) + returns Boolean from Standard; + ---Purpose: Return true if F has same domain faces + + IsSameDomainF(me; F1, F2 : Shape from TopoDS) + returns Boolean from Standard; + ---Purpose: Return true if F1 and F2 are same domain faces + + SameDomain(me; F : Face from TopoDS) + returns ListOfShape from TopTools; + ---C++: return const & + ---Purpose: Return same domain faces of F + + ReplaceSameDomainV (me; V : Vertex from TopoDS; + E : Edge from TopoDS) + returns Vertex from TopoDS; + ---Purpose: return same domain vertex of V if it was replaced + -- and make this vertex to be on E too, else return V + + -------------------------- + ---Category: Section edges + -------------------------- + + SectionEdgesAD (me) returns AsDes from BRepAlgo + is static; + + IsSectionEdge (me; E : Edge from TopoDS) + returns Boolean from Standard; + ---Purpose: return True if E is an edge of an initial face and + -- E intersects aother face + + HasSectionEdge (me; F : Face from TopoDS) + returns Boolean from Standard; + ---Purpose: return True if F is intersected by an edge of + -- other face + + IsSplitOn (me; NewE, OldE : Edge from TopoDS; + F : Face from TopoDS) + returns Boolean from Standard; + ---Purpose: return True if NewE is split of OldE on F; + -- no check if NewE is split of OldE :) + + SectionEdgeFaces (me; SecE : Edge from TopoDS) + returns ListOfShape from TopTools; + ---C++: return const& + ---Purpose: return faces cut by section edge + + -------------------- + ---Category: Private + -------------------- + + Inter3D (me: in out; F1, F2 : Face from TopoDS; + LInt : in out ListOfShape from TopTools) + is static private; + + StorePart3d(me : in out; F1,F2 : Face from TopoDS; + LInt1 : ListOfShape from TopTools) + is static private; + + SetDone(me : in out; F1,F2 : Face from TopoDS) + is static private; + + Affiche (me; SetOfFaces : ListOfShape from TopTools) + is static private; + +fields + + myAsDes : AsDes from BRepAlgo; + myDone : DataMapOfShapeListOfShape from TopTools; + myTouched : MapOfShape from TopTools; + myNewEdges : MapOfShape from TopTools; + + -- section edges: existing edges that are intersection lines, + -- may be partially. + -- Store as + -- FACE -> SECTION EDGES, SECTION EDGE -> OTHER SECTION EDGE + mySectionEdgesAD : AsDes from BRepAlgo; + + -- same domain shapes + -- faces + mySameDomainFM : DataMapOfShapeListOfShape from TopTools; + -- vertex -> vertex replacement + mySameDomainVM : DataMapOfShapeShape from TopTools; + +end Inter3d; diff --git a/PARTITION/Partition_Inter3d.cxx b/PARTITION/Partition_Inter3d.cxx new file mode 100644 index 000000000..dc7e4606c --- /dev/null +++ b/PARTITION/Partition_Inter3d.cxx @@ -0,0 +1,861 @@ +// 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 +// +// +// +// File : Partition_Inter3d.cxx +// Author : Benedicte MARTIN +// Module : GEOM +// $Header$ + +using namespace std; +#include "Partition_Inter3d.ixx" +#include "Partition_Inter2d.hxx" +#include "utilities.h" + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef DEB +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//======================================================================= +//function : Partition_Inter3d +//purpose : +//======================================================================= + +Partition_Inter3d::Partition_Inter3d() +{ +} +//======================================================================= +//function : Partition_Inter3d +//purpose : +//======================================================================= + +Partition_Inter3d::Partition_Inter3d(const Handle(BRepAlgo_AsDes)& AsDes) + :myAsDes(AsDes) +{ + mySectionEdgesAD = new BRepAlgo_AsDes; +} + +//======================================================================= +//function : CompletPart3d +//purpose : FaceShapeMap is just to know the shape a face belongs to +//======================================================================= + +void Partition_Inter3d::CompletPart3d(const TopTools_ListOfShape& SetOfFaces1, + const TopTools_DataMapOfShapeShape& FaceShapeMap) +{ + if (myAsDes.IsNull()) + myAsDes = new BRepAlgo_AsDes; + + TopTools_ListIteratorOfListOfShape it; + + //--------------------------------------------------------------- + // Construction of bounding boxes. + //--------------------------------------------------------------- + + BRep_Builder B; + TopoDS_Compound CompOS; + B.MakeCompound(CompOS); + for (it.Initialize(SetOfFaces1); it.More(); it.Next()) + B.Add(CompOS, it.Value()); + + TopOpeBRepTool_BoxSort BOS; + BOS.AddBoxesMakeCOB(CompOS,TopAbs_FACE); + + for (it.Initialize(SetOfFaces1); it.More(); it.Next()) { + TopoDS_Face F1 = TopoDS::Face(it.Value()); + + // avoid intersecting faces of one shape + TopoDS_Shape S1; + if (FaceShapeMap.IsBound(F1)) S1 = FaceShapeMap.Find(F1); + // avoid intersecting faces sharing vertices, suppose they belong to + // shapes sharing same faces + TopTools_IndexedMapOfShape VM; + TopExp::MapShapes( F1, TopAbs_VERTEX, VM); + + TColStd_ListIteratorOfListOfInteger itLI = BOS.Compare(F1); + for (; itLI.More(); itLI.Next()) { + TopoDS_Face F2 = TopoDS::Face(BOS.TouchedShape(itLI)); + if (F1.IsSame(F2) || IsDone(F1,F2)) + continue; + + TopoDS_Shape S2; + if (FaceShapeMap.IsBound(F2)) S2 = FaceShapeMap.Find(F2); + if (!S1.IsNull() && S1.IsSame(S2)) + continue; // descendants of one shape + + TopExp_Explorer expV (F2, TopAbs_VERTEX); + for ( ; expV.More(); expV.Next()) + if (VM.Contains( expV.Current() )) + break; + if (expV.More()) + continue; // faces have a common edge + + F1.Orientation(TopAbs_FORWARD); + F2.Orientation(TopAbs_FORWARD); + FacesPartition(F1,F2); + } + + // mark as modified a face which has at least one new edge + if (!myAsDes->HasDescendant( F1 )) + continue; + TopTools_ListIteratorOfListOfShape itE (myAsDes->Descendant( F1 )); + for ( ; itE.More(); itE.Next()) { + if (myNewEdges.Contains( itE.Value())) { + myTouched.Add( F1 ); + break; + } + } + } +} + +//======================================================================= +//function : PutInBounds +//purpose : +//======================================================================= + +static void PutInBounds (const TopoDS_Face& F, + const TopoDS_Edge& E, + Handle(Geom2d_Curve)& C2d) +{ + Standard_Real umin,umax,vmin,vmax; + Standard_Real f,l; + BRep_Tool::Range(E,f,l); + + TopLoc_Location L; // Recup S avec la location pour eviter la copie. + Handle (Geom_Surface) S = BRep_Tool::Surface(F,L); + + if (S->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) { + S = (*(Handle_Geom_RectangularTrimmedSurface*)&S)->BasisSurface(); + } + //--------------- + // Recadre en U. + //--------------- + if (!S->IsUPeriodic() && !S->IsVPeriodic()) return; + + BRepTools::UVBounds(F,umin,umax,vmin,vmax); + + 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.; + if (minC< umin - eps) { + du = (int((umin - minC)/period) + 1)*period; + } + if (minC > umax + eps) { + du = -(int((minC - umax)/period) + 1)*period; + } + if (du != 0) { + gp_Vec2d T1(du,0.); + C2d->Translate(T1); + minC += du; maxC += du; + } + // Ajuste au mieux la courbe dans le domaine. + if (maxC > umax +100*eps) { + Standard_Real d1 = maxC - umax; + Standard_Real d2 = umin - minC + period; + if (d2 < d1) du =-period; + if ( du != 0.) { + gp_Vec2d T2(du,0.); + C2d->Translate(T2); + } + } + } + //------------------ + // Recadre en V. + //------------------ + 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.; + if (minC< vmin - eps) { + dv = (int((vmin - minC)/period) + 1)*period; + } + if (minC > vmax + eps) { + dv = -(int((minC - vmax)/period) + 1)*period; + } + if (dv != 0) { + gp_Vec2d T1(0.,dv); + C2d->Translate(T1); + minC += dv; maxC += dv; + } + // Ajuste au mieux la courbe dans le domaine. + if (maxC > vmax +100*eps) { + Standard_Real d1 = maxC - vmax; + Standard_Real d2 = vmin - minC + period; + if (d2 < d1) dv =-period; + if ( dv != 0.) { + gp_Vec2d T2(0.,dv); + C2d->Translate(T2); + } + } + } +} + +//======================================================================= +//function : Inter3D +//purpose : +//======================================================================= + +void Partition_Inter3d::Inter3D(const TopoDS_Face& F1, + const TopoDS_Face& F2, + TopTools_ListOfShape& L) +{ + BRep_Builder B; + + // fill the data Structure + Handle(TopOpeBRepDS_HDataStructure) DatStr = new TopOpeBRepDS_HDataStructure(); + TopOpeBRep_DSFiller DSFiller; + DSFiller.Insert(F1,F2,DatStr); + + // define the GeomTool used by the DSFiller : + // compute BSpline of degree 1 on intersection curves. + Standard_Real tol3dAPPROX = 1e-7; + Standard_Real tol2dAPPROX = 1e-7; + TopOpeBRepTool_GeomTool GT2 (TopOpeBRepTool_APPROX); + GT2.SetTolerances(tol3dAPPROX,tol2dAPPROX); + TopOpeBRepDS_BuildTool BT(GT2); + + // Perform Section + TopOpeBRepBuild_Builder TopB(BT); + TopB.Perform(DatStr); + + // =============== + // Store new edges + // =============== + + L.Clear(); + TopOpeBRepDS_CurveExplorer cex(DatStr->DS()); + for (; cex.More(); cex.Next()) { + const TopOpeBRepDS_Curve& CDS = cex.Curve(); + Standard_Integer ic = cex.Index(); + Handle(Geom2d_Curve) pc1 = CDS.Curve1(); + Handle(Geom2d_Curve) pc2 = CDS.Curve2(); + + TopTools_ListIteratorOfListOfShape itLE = TopB.NewEdges(ic); + 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); + + B.UpdateEdge (E,pc1,F1,0.); + B.UpdateEdge (E,pc2,F2,0.); + + L.Append (E); + + itLE.Next(); + if (itLE.More()) { + pc1 = Handle(Geom2d_Curve)::DownCast(pc1->Copy()); + pc2 = Handle(Geom2d_Curve)::DownCast(pc2->Copy()); + } + } + } + + // =================================================== + // Store section edges, same domain faces and verives + // =================================================== + + TopTools_ListOfShape empty, LSP, LSE; + + if ( DatStr->HasSameDomain( F1 )) { // same domain faces + if (!mySameDomainFM.IsBound(F1)) + mySameDomainFM.Bind(F1,empty); + if (!mySameDomainFM.IsBound(F2)) + mySameDomainFM.Bind(F2,empty); + mySameDomainFM(F1).Append(F2); + mySameDomainFM(F2).Append(F1); + } + + const TopOpeBRepDS_DataStructure& DS = DatStr->DS(); + Standard_Integer j,i,nes = DS.NbSectionEdges(); + if (!nes) return; + + + TopoDS_Vertex V, sdeV1, sdeV2; + TopTools_MapOfShape MV; + + // 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); + if (! TopB.IsSplit(se,TopAbs_ON)) + continue; + + if (DatStr->HasSameDomain(se)) { + sde = TopoDS::Edge( DatStr->SameDomain(se).Value() ); + TopExp::Vertices( sde, sdeV1, sdeV2); + } + + TColStd_MapOfInteger MIV; + TopOpeBRepDS_PointIterator itP (DS.ShapeInterferences( se )); + itP.SupportKind( TopOpeBRepDS_EDGE ); + for (; itP.More(); itP.Next()) { + oe = TopoDS::Edge( DS.Shape( itP.Support())); + if (itP.IsVertex()) { + if ( !MIV.Add( itP.Current() )) + continue; + V = TopoDS::Vertex( DS.Shape( itP.Current())); + if ( !sde.IsNull() && (V.IsSame(sdeV1) || V.IsSame(sdeV2)) ) + oe = sde; + V = ReplaceSameDomainV( V , oe ); + V.Orientation( TopAbs_INTERNAL); + B.UpdateVertex( V, itP.Parameter(), se, 0.); + } + else { + const TopOpeBRepDS_Point& DSP = DS.Point( itP.Current()); + V = BRepLib_MakeVertex( DSP.Point() ); + V.Orientation( TopAbs_INTERNAL); + B.UpdateVertex( V, itP.Parameter(), se, DSP.Tolerance()); + // make V be on the other edge + TopOpeBRepDS_PointIterator itOP (DS.ShapeInterferences( oe )); + for (; itOP.More(); itOP.Next()) { + const TopOpeBRepDS_Point& ODSP = DS.Point( itOP.Current()); + if ( DSP.IsEqual (ODSP)) { + B.UpdateVertex( V, itOP.Parameter(), TopoDS::Edge(oe), ODSP.Tolerance()); + break; + } + } + } + TopoDS_Vertex addedV = Partition_Inter2d::AddVonE( V,se,oe,myAsDes); + if (!addedV.IsSame( V )) + mySameDomainVM.Bind (V, addedV); + MV.Add( addedV ); + } + } + + TopB.SplitSectionEdges(); + + TopTools_DataMapOfShapeShape SEM; // map split - section edge + 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++) { + + const TopoDS_Edge& se = DS.SectionEdge(i); + if (! TopB.IsSplit(se,TopAbs_ON)) + continue; + + Standard_Integer ancRank = DS.AncestorRank(se); + if (ME[ancRank-1].Contains( se )) + continue; // se is an edge of face it intersects + + const TopoDS_Face& F = (ancRank == 1) ? F2 : F1; + + // add se to face but dont add twice + TopTools_ListIteratorOfListOfShape itE; + if (myAsDes->HasDescendant( F )) { + for (itE.Initialize( (myAsDes->Descendant( F )) ); itE.More(); itE.Next()) + if (se.IsSame( itE.Value() )) + break; + } + if (!itE.More()) { + myAsDes->Add( F, se ); + 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()); + BRep_Tool::Range(E, f, l); + umin = Min( umin, f); + umax = Max( umax, l); + } + Handle(Geom_Curve) C3d = BRep_Tool::Curve( se, f, l); + if (umin < umax) // sometimes umin == umax for closed edge + C3d = new Geom_TrimmedCurve( C3d, umin, umax); + pc = TopOpeBRepTool_CurveTool::MakePCurveOnFace (F,C3d,tol); + if (pc.IsNull()) { + MESSAGE (" CANT BUILD PCURVE "); + } + 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); + } + } + + // 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; + + 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 + 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 )) + continue; + + added = Standard_True; + mySectionEdgesAD->Add( F, se ); + + TopoDS_Vertex VS[2]; + TopExp::Vertices (S, VS[0], VS[1]); + for (j=0; j<2; ++j) { + if (mySameDomainVM.IsBound( VS[j] )) + VS[j] = TopoDS::Vertex( mySameDomainVM( VS[j] )); + if ( !MV.Contains( VS[j] )) { + // find equal vertex on se - point interference + gp_Pnt P1 = BRep_Tool::Pnt( VS[j] ); + TopTools_ListIteratorOfListOfShape itV( myAsDes->Descendant(se) ); + for (; itV.More(); itV.Next()) { + V = TopoDS::Vertex( itV.Value() ); + gp_Pnt P2 = BRep_Tool::Pnt( V ); + if (P1.IsEqual( P2, Precision::Confusion())) { + mySameDomainVM.Bind (VS[j], V); + VS[j] = V; + break; + } + } + if (!itV.More()) // no interferences with edges + myAsDes->Add( se, VS[j]); + } + mySectionEdgesAD->Add( F, VS[j]); + } + mySectionEdgesAD->Add( F, S ); + } + if (!added) + mySectionEdgesAD->Add( F, se ); + + myNewEdges.Add( se ); + } +} + +//======================================================================= +//function : FacesPartition +//purpose : +//======================================================================= + +void Partition_Inter3d::FacesPartition(const TopoDS_Face& F1, + const TopoDS_Face& F2) + //(const TopTools_DataMapOfShapeListOfShape& /*SetOfFaces2*/) +{ + TopTools_ListOfShape LInt; + + Inter3D (F1,F2,LInt); + + StorePart3d (F1,F2,LInt); +} + +//======================================================================= +//function : SetDone +//purpose : +//======================================================================= + +void Partition_Inter3d::SetDone(const TopoDS_Face& F1, + const TopoDS_Face& F2) +{ + if (!myDone.IsBound(F1)) { + TopTools_ListOfShape empty; + myDone.Bind(F1,empty); + } + myDone(F1).Append(F2); + if (!myDone.IsBound(F2)) { + TopTools_ListOfShape empty; + myDone.Bind(F2,empty); + } + myDone(F2).Append(F1); +} + +//======================================================================= +//function : IsDone +//purpose : +//======================================================================= + +Standard_Boolean Partition_Inter3d::IsDone(const TopoDS_Face& F1, + const TopoDS_Face& F2) + + const +{ + if (myDone.IsBound(F1)) { + TopTools_ListIteratorOfListOfShape it (myDone(F1)); + for (; it.More(); it.Next()) { + if (it.Value().IsSame(F2)) return Standard_True; + } + } + return Standard_False; +} + +//======================================================================= +//function : StorePart3d +//purpose : +//======================================================================= + +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); + + TopTools_ListIteratorOfListOfShape it(LInt); + for (; it.More(); it.Next()) { + + TopoDS_Edge E = TopoDS::Edge(it.Value()); + + BRep_Builder B; + B.SameParameter(E,Standard_False); + BRepLib::SameParameter(E,1.0e-7); + + myNewEdges.Add(E); + } + } + SetDone(F1,F2); +} + +//======================================================================= +//function : TouchedFaces +//purpose : +//======================================================================= + +TopTools_MapOfShape& Partition_Inter3d::TouchedFaces() +{ + return myTouched; +} + +//======================================================================= +//function : AsDes +//purpose : +//======================================================================= + +Handle(BRepAlgo_AsDes) Partition_Inter3d::AsDes() const +{ + return myAsDes; +} + +//======================================================================= +//function : NewEdges +//purpose : +//======================================================================= + +TopTools_MapOfShape& Partition_Inter3d::NewEdges() +{ + return myNewEdges; +} + +//======================================================================= +//function : Affiche +//purpose : +//======================================================================= + +void Partition_Inter3d::Affiche(const TopTools_ListOfShape& SetOfFaces) const +{ +#ifdef DEB + char PSection[1024]; + char *section=PSection; + Standard_Integer i = 0; + Standard_Real j=1; + TopTools_ListOfShape aList; + TopTools_ListIteratorOfListOfShape it; + for (it.Initialize(SetOfFaces); it.More(); it.Next()) { + const TopoDS_Shape& OS = it.Value(); + aList=myAsDes->Descendant(OS); + MESSAGE ( " the number of items stored in the list " << j << " : " << aList.Extent() ) + j++; + TopTools_ListIteratorOfListOfShape itaList; + for (itaList.Initialize(aList); itaList.More(); itaList.Next()) { + const TopoDS_Shape& SS = itaList.Value(); + i++; + sprintf(PSection,"section_%d",i); + DBRep::Set(section,SS); + } + } +#endif +} + +//======================================================================= +//function : SameDomain +//purpose : +//======================================================================= + +const TopTools_ListOfShape& Partition_Inter3d::SameDomain(const TopoDS_Face& F) const +{ + if (mySameDomainFM.IsBound( F )) + return mySameDomainFM (F); + + static TopTools_ListOfShape empty; + return empty; +} + +//======================================================================= +//function : HasSameDomainF +//purpose : Return true if F has same domain faces +//======================================================================= + +Standard_Boolean Partition_Inter3d::HasSameDomainF(const TopoDS_Shape& F) const +{ + return mySameDomainFM.IsBound( F ); +} + +//======================================================================= +//function : IsSameDomain +//purpose : Return true if F1 and F2 are same domain faces +//======================================================================= + +Standard_Boolean Partition_Inter3d::IsSameDomainF(const TopoDS_Shape& F1, + const TopoDS_Shape& F2) const +{ + if (mySameDomainFM.IsBound( F1 )) { + TopTools_ListIteratorOfListOfShape it (mySameDomainFM( F1 )); + for (; it.More(); it.Next()) + if (F2.IsSame( it.Value())) + return Standard_True; + } + return F1.IsSame( F2 ); +} + +//======================================================================= +//function : ReplaceSameDomainV +//purpose : return same domain vertex of V if it was replaced +// and make this vertex to be on E too, else return V +//======================================================================= + +TopoDS_Vertex Partition_Inter3d::ReplaceSameDomainV(const TopoDS_Vertex& V, + const TopoDS_Edge& E) const +{ + TopoDS_Vertex SDV = V; + if (mySameDomainVM.IsBound( V )) { + + TopoDS_Vertex V1,V2; + TopExp::Vertices(E,V1,V2); + Standard_Boolean isClosed = V1.IsSame( V2 ) && V.IsSame(V1); + + SDV = TopoDS::Vertex( mySameDomainVM(V) ); + Standard_Real tol = BRep_Tool::Tolerance( V ); + BRep_Builder B; + SDV.Orientation( V.Orientation()); + + if (isClosed) { + Standard_Real f, l; + BRep_Tool::Range (E, f, l); + Standard_Boolean isFirst = IsEqual( BRep_Tool::Parameter(V,E), f ); + B.UpdateVertex(SDV, (isFirst ? f : l), E, tol); + SDV.Reverse(); + B.UpdateVertex(SDV, (isFirst ? l : f), E, tol); + } + else + B.UpdateVertex (SDV, BRep_Tool::Parameter(V,E), E, tol); + + } + return SDV; +} + +//======================================================================= +//function : SectionEdgesAD +//purpose : +//======================================================================= + +Handle(BRepAlgo_AsDes) Partition_Inter3d::SectionEdgesAD() const +{ + return mySectionEdgesAD; +} + +//======================================================================= +//function : IsSectionEdge +//purpose : return True if E is an edge of a face and it +// intersects an other face +//======================================================================= + +Standard_Boolean + Partition_Inter3d::IsSectionEdge(const TopoDS_Edge& E) const +{ + return mySectionEdgesAD->HasAscendant(E); +} + +//======================================================================= +//function : HasSectionEdge +//purpose : return True if an edge of F intersects an other +// face or F is intersected by edge of an other face +//======================================================================= + +Standard_Boolean + Partition_Inter3d::HasSectionEdge(const TopoDS_Face& F) const +{ + return mySectionEdgesAD->HasDescendant(F); +} + +//======================================================================= +//function : IsSplitOn +//purpose : return True if NewE is split of OldE on F +//======================================================================= + +Standard_Boolean + Partition_Inter3d::IsSplitOn(const TopoDS_Edge& NewE, + const TopoDS_Edge& OldE, + const TopoDS_Face& F) const +{ + if (! mySectionEdgesAD->HasDescendant(F)) + return Standard_False; + + TopTools_ListIteratorOfListOfShape itE ( mySectionEdgesAD->Descendant(F) ); + for ( ; itE.More(); itE.Next()) { + if ( itE.Value().ShapeType() != TopAbs_EDGE || + ! OldE.IsSame ( itE.Value() )) + continue; + // an edge encountered, its vertices and a split come next + itE.Next(); + if (!itE.More()) break; + const TopoDS_Shape& V3 = itE.Value(); + if (V3.ShapeType() != TopAbs_VERTEX) continue; + itE.Next(); + if (!itE.More()) break; + const TopoDS_Shape& V4 = itE.Value(); + if (V4.ShapeType() != TopAbs_VERTEX) continue; + + TopoDS_Vertex V1, V2; + TopExp::Vertices( OldE, V1, V2); + + if ( V1.IsSame(V2) && + (V1.IsSame(V3) || V1.IsSame(V4)) ) { + // closed old edge; use the split for the test + itE.Next(); + if (!itE.More()) break; + const TopoDS_Edge& split = TopoDS::Edge( itE.Value() ); + // check distance at middle point of NewE + Standard_Real f1,l1, f2,l2; + Handle(Geom2d_Curve) PC1 = BRep_Tool::CurveOnSurface( split, F ,f1,l1); + if (!PC1.IsNull()) { + Handle(Geom2d_Curve) PC2 = BRep_Tool::CurveOnSurface(NewE, F ,f2,l2); + gp_Pnt2d P = PC2->Value( 0.5*(f2+l2) ); + Geom2dAPI_ProjectPointOnCurve proj (P, PC1, f1, l1); + if (proj.NbPoints() && + proj.LowerDistance() <= Precision::Confusion()) + return Standard_True; + } + else { + Handle(Geom_Curve) C1 = BRep_Tool::Curve( split ,f1,l1); + Handle(Geom_Curve) C2 = BRep_Tool::Curve( NewE ,f2,l2); + gp_Pnt P = C2->Value( 0.5*(f2+l2) ); + GeomAPI_ProjectPointOnCurve proj (P, C1, f1, l1); + if (proj.NbPoints() && + proj.LowerDistance() <= Precision::Confusion()) + return Standard_True; + } + } + else { + Standard_Real u3 = BRep_Tool::Parameter( TopoDS::Vertex(V3), OldE); + Standard_Real u4 = BRep_Tool::Parameter( TopoDS::Vertex(V4), OldE); + + Standard_Real f,l, u; + BRep_Tool::Range( NewE, f,l); + u = 0.5*(f+l); + f = Min(u3,u4); + l = Max(u3,u4); + + if (u <= l && u >= f) + return Standard_True; + } + } + return Standard_False; +} + +//======================================================================= +//function : SectionEdgeFaces +//purpose : return faces cut by section edge +//======================================================================= + +const TopTools_ListOfShape& + Partition_Inter3d::SectionEdgeFaces(const TopoDS_Edge& SecE) const +{ + return mySectionEdgesAD->Ascendant( SecE ); +} diff --git a/PARTITION/Partition_Inter3d.hxx b/PARTITION/Partition_Inter3d.hxx new file mode 100644 index 000000000..57e8da43f --- /dev/null +++ b/PARTITION/Partition_Inter3d.hxx @@ -0,0 +1,143 @@ +// 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 +// +// +// +// File : Partition_Inter3d.hxx +// Module : GEOM + +#ifndef _Partition_Inter3d_HeaderFile +#define _Partition_Inter3d_HeaderFile + +#ifndef _Handle_BRepAlgo_AsDes_HeaderFile +#include +#endif +#ifndef _TopTools_DataMapOfShapeListOfShape_HeaderFile +#include +#endif +#ifndef _TopTools_MapOfShape_HeaderFile +#include +#endif +#ifndef _TopTools_DataMapOfShapeShape_HeaderFile +#include +#endif +#ifndef _Standard_Boolean_HeaderFile +#include +#endif +class BRepAlgo_AsDes; +class TopTools_ListOfShape; +class TopTools_DataMapOfShapeShape; +class TopoDS_Face; +class TopTools_MapOfShape; +class TopoDS_Shape; +class TopoDS_Vertex; +class TopoDS_Edge; + + +#ifndef _Standard_HeaderFile +#include +#endif +#ifndef _Standard_Macro_HeaderFile +#include +#endif + +class Partition_Inter3d { + +public: + + void* operator new(size_t,void* anAddress) + { + return anAddress; + } + void* operator new(size_t size) + { + return Standard::Allocate(size); + } + void operator delete(void *anAddress) + { + if (anAddress) Standard::Free((Standard_Address&)anAddress); + } + // Methods PUBLIC + // +Standard_EXPORT Partition_Inter3d(); +Standard_EXPORT Partition_Inter3d(const Handle(BRepAlgo_AsDes)& AsDes); +Standard_EXPORT void CompletPart3d(const TopTools_ListOfShape& SetOfFaces1,const TopTools_DataMapOfShapeShape& FaceShapeMap) ; +Standard_EXPORT void FacesPartition(const TopoDS_Face& F1,const TopoDS_Face& F2) ; +Standard_EXPORT Standard_Boolean IsDone(const TopoDS_Face& F1,const TopoDS_Face& F2) const; +Standard_EXPORT TopTools_MapOfShape& TouchedFaces() ; +Standard_EXPORT Handle_BRepAlgo_AsDes AsDes() const; +Standard_EXPORT TopTools_MapOfShape& NewEdges() ; +Standard_EXPORT Standard_Boolean HasSameDomainF(const TopoDS_Shape& F) const; +Standard_EXPORT Standard_Boolean IsSameDomainF(const TopoDS_Shape& F1,const TopoDS_Shape& F2) const; +Standard_EXPORT const TopTools_ListOfShape& SameDomain(const TopoDS_Face& F) const; +Standard_EXPORT TopoDS_Vertex ReplaceSameDomainV(const TopoDS_Vertex& V,const TopoDS_Edge& E) const; +Standard_EXPORT Handle_BRepAlgo_AsDes SectionEdgesAD() const; +Standard_EXPORT Standard_Boolean IsSectionEdge(const TopoDS_Edge& E) const; +Standard_EXPORT Standard_Boolean HasSectionEdge(const TopoDS_Face& F) const; +Standard_EXPORT Standard_Boolean IsSplitOn(const TopoDS_Edge& NewE,const TopoDS_Edge& OldE,const TopoDS_Face& F) const; +Standard_EXPORT const TopTools_ListOfShape& SectionEdgeFaces(const TopoDS_Edge& SecE) const; + + + + + +protected: + + // Methods PROTECTED + // + + + // Fields PROTECTED + // + + +private: + + // Methods PRIVATE + // +Standard_EXPORT void Inter3D(const TopoDS_Face& F1,const TopoDS_Face& F2,TopTools_ListOfShape& LInt) ; +Standard_EXPORT void StorePart3d(const TopoDS_Face& F1,const TopoDS_Face& F2,const TopTools_ListOfShape& LInt1) ; +Standard_EXPORT void SetDone(const TopoDS_Face& F1,const TopoDS_Face& F2) ; +Standard_EXPORT void Affiche(const TopTools_ListOfShape& SetOfFaces) const; + + + // Fields PRIVATE + // +Handle_BRepAlgo_AsDes myAsDes; +TopTools_DataMapOfShapeListOfShape myDone; +TopTools_MapOfShape myTouched; +TopTools_MapOfShape myNewEdges; +Handle_BRepAlgo_AsDes mySectionEdgesAD; +TopTools_DataMapOfShapeListOfShape mySameDomainFM; +TopTools_DataMapOfShapeShape mySameDomainVM; + + +}; + + + + + +// other Inline functions and methods (like "C++: function call" methods) +// + + +#endif diff --git a/PARTITION/Partition_Inter3d.ixx b/PARTITION/Partition_Inter3d.ixx new file mode 100644 index 000000000..0775cc99c --- /dev/null +++ b/PARTITION/Partition_Inter3d.ixx @@ -0,0 +1,31 @@ +// 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 +// +// +// +// File : Partition_Inter3d.ixx +// Module : GEOM + +#include "Partition_Inter3d.jxx" + + + + diff --git a/PARTITION/Partition_Inter3d.jxx b/PARTITION/Partition_Inter3d.jxx new file mode 100644 index 000000000..5804ba81e --- /dev/null +++ b/PARTITION/Partition_Inter3d.jxx @@ -0,0 +1,53 @@ +// 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 +// +// +// +// File : Partition_Inter3d.jxx +// Module : GEOM + +#ifndef _BRepAlgo_AsDes_HeaderFile +#include +#endif +#ifndef _TopTools_ListOfShape_HeaderFile +#include +#endif +#ifndef _TopTools_DataMapOfShapeShape_HeaderFile +#include +#endif +#ifndef _TopoDS_Face_HeaderFile +#include +#endif +#ifndef _TopTools_MapOfShape_HeaderFile +#include +#endif +#ifndef _TopoDS_Shape_HeaderFile +#include +#endif +#ifndef _TopoDS_Vertex_HeaderFile +#include +#endif +#ifndef _TopoDS_Edge_HeaderFile +#include +#endif +#ifndef _Partition_Inter3d_HeaderFile +#include "Partition_Inter3d.hxx" +#endif diff --git a/PARTITION/Partition_Loop.cdl b/PARTITION/Partition_Loop.cdl new file mode 100644 index 000000000..eb6ec67a9 --- /dev/null +++ b/PARTITION/Partition_Loop.cdl @@ -0,0 +1,87 @@ +-- 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 +-- +-- +-- +-- File : Partition_Loop.cdl +-- Author : Benedicte MARTIN +-- Module : GEOM + +class Loop from Partition + + ---Purpose: Builds the loops from a set of edges on a face. + +uses + + Face from TopoDS, + Edge from TopoDS, + ListOfShape from TopTools, + DataMapOfShapeListOfShape from TopTools + +is + + Create; + + Init (me : in out; F : Face from TopoDS) + ---Purpose: Init with the set of edges must have + -- pcurves on . + is static; + + AddEdge (me : in out; E : in out Edge from TopoDS; + LV : ListOfShape from TopTools) + ---Purpose: Add E with . will be copied and trim + -- by vertices in . + is static; + + AddConstEdge (me : in out; E : Edge from TopoDS) + ---Purpose: Add as const edge, E can be in the result. + is static; + + Perform(me : in out) + ---Purpose: Make loops. + is static; + + NewWires (me) + ---Purpose: Returns the list of wires performed. + -- can be an empty list. + ---C++: return const & + returns ListOfShape from TopTools; + + WiresToFaces (me : in out) + ---Purpose: Build faces from the wires result. + is static; + + NewFaces (me) + ---Purpose: Returns the list of faces. + ---Warning: The method as to be called before. + -- can be an empty list. + ---C++: return const & + returns ListOfShape from TopTools; + + +fields + + myFace : Face from TopoDS; + myConstEdges : ListOfShape from TopTools; + myNewWires : ListOfShape from TopTools; + myNewFaces : ListOfShape from TopTools; + +end Loop; diff --git a/PARTITION/Partition_Loop.cxx b/PARTITION/Partition_Loop.cxx new file mode 100644 index 000000000..29386de22 --- /dev/null +++ b/PARTITION/Partition_Loop.cxx @@ -0,0 +1,467 @@ +// 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 +// +// +// +// File : Partition_Loop.cxx +// Author : Benedicte MARTIN +// Module : GEOM +// $Header$ + +using namespace std; +#include + +#include "Partition_Loop.ixx" + +#include "utilities.h" + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +static char* name = new char[100]; +static int nbe = 0; + +//======================================================================= +//function : Partition_Loop +//purpose : +//======================================================================= +Partition_Loop::Partition_Loop() +{ +} + +//======================================================================= +//function : Init +//purpose : +//======================================================================= +void Partition_Loop::Init(const TopoDS_Face& F) +{ + myConstEdges.Clear(); + myNewWires .Clear(); + myNewFaces .Clear(); + myFace = F; +} + +//======================================================================= +//function : AddConstEdge +//purpose : +//======================================================================= +void Partition_Loop::AddConstEdge (const TopoDS_Edge& E) +{ + myConstEdges.Append(E); +} + + +//======================================================================= +//function : FindDelta +//purpose : +//======================================================================= +static Standard_Real FindDelta(TopTools_ListOfShape& LE, + const TopoDS_Face& F) +{ + Standard_Real dist, f, l; + Standard_Real d = Precision::Infinite(); + TopTools_ListIteratorOfListOfShape itl; + + for ( itl.Initialize(LE); itl.More(); itl.Next()) { + const TopoDS_Edge& E = TopoDS::Edge(itl.Value()); + Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(E,F,f,l); + gp_Pnt2d p = C->Value(f); + gp_Pnt2d pp = C->Value(l); + Standard_Real d1 = p.Distance(pp); + if (d1 connected by the vertex in the list . +// Is erased of the list. If is too in the list +// with the same orientation, it's erased of the list +//======================================================================= +static Standard_Boolean SelectEdge(const TopoDS_Face& F, + const TopoDS_Edge& CE, + const TopoDS_Vertex& CV, + TopoDS_Edge& NE, + TopTools_ListOfShape& LE) +{ + TopTools_ListIteratorOfListOfShape itl; + NE.Nullify(); + for ( itl.Initialize(LE); itl.More(); itl.Next()) { + if (itl.Value().IsEqual(CE)) { + LE.Remove(itl); + break; + } + } + + if (LE.Extent() > 1) { + //-------------------------------------------------------------- + // Several possible edges. + // - Test the edges differents of CE + //-------------------------------------------------------------- + Standard_Real cf, cl, f, l; + TopoDS_Face FForward = F; + Handle(Geom2d_Curve) Cc, C; + FForward.Orientation(TopAbs_FORWARD); + + Cc = BRep_Tool::CurveOnSurface(CE,FForward,cf,cl); + Standard_Real dist,distmin = 100*BRep_Tool::Tolerance(CV); + Standard_Real uc,u; + if (CE.Orientation () == TopAbs_FORWARD) uc = cl; + else uc = cf; + + gp_Pnt2d P2,PV = Cc->Value(uc); + + Standard_Real delta = FindDelta(LE,FForward); + + for ( itl.Initialize(LE); itl.More(); itl.Next()) { + const TopoDS_Edge& E = TopoDS::Edge(itl.Value()); + if (!E.IsSame(CE)) { + C = BRep_Tool::CurveOnSurface(E,FForward,f,l); + if (E.Orientation () == TopAbs_FORWARD) u = f; + else u = l; + P2 = C->Value(u); + dist = PV.Distance(P2); + if (dist <= distmin){ + distmin = dist; + } + + } + } + + Standard_Real anglemax = - PI; + TopoDS_Edge SelectedEdge; + for ( itl.Initialize(LE); itl.More(); itl.Next()) { + const TopoDS_Edge& E = TopoDS::Edge(itl.Value()); + if (!E.IsSame(CE)) { + C = BRep_Tool::CurveOnSurface(E,FForward,f,l); + if (E.Orientation () == TopAbs_FORWARD) u = f; + else u = l; + P2 = C->Value(u); + dist = PV.Distance(P2); + if (dist <= distmin + (1./3)*delta){ + gp_Pnt2d PC, P; + gp_Vec2d CTg1, CTg2, Tg1, Tg2; + Cc->D2(uc, PC, CTg1, CTg2); + C->D2(u, P, Tg1, Tg2); + + Standard_Real angle; + + if (CE.Orientation () == TopAbs_REVERSED && E.Orientation () == TopAbs_FORWARD) { + angle = CTg1.Angle(Tg1.Reversed()); + } + else if (CE.Orientation () == TopAbs_FORWARD && E.Orientation () == TopAbs_REVERSED) { + angle = (CTg1.Reversed()).Angle(Tg1); + } + else if (CE.Orientation () == TopAbs_REVERSED && E.Orientation () == TopAbs_REVERSED) { + angle = CTg1.Angle(Tg1); + } + else if (CE.Orientation () == TopAbs_FORWARD && E.Orientation () == TopAbs_FORWARD) { + angle = (CTg1.Reversed()).Angle(Tg1.Reversed()); + } + if (angle >= anglemax) { + anglemax = angle ; + SelectedEdge = E; + } + } + } + } + for ( itl.Initialize(LE); itl.More(); itl.Next()) { + const TopoDS_Edge& E = TopoDS::Edge(itl.Value()); + if (E.IsEqual(SelectedEdge)) { + NE = TopoDS::Edge(E); + LE.Remove(itl); + break; + } + } + } + else if (LE.Extent() == 1) { + NE = TopoDS::Edge(LE.First()); + LE.RemoveFirst(); + } + else { + return Standard_False; + } + return Standard_True; +} + +//======================================================================= +//function : SamePnt2d +//purpose : +//======================================================================= +static Standard_Boolean SamePnt2d(TopoDS_Vertex V, + TopoDS_Edge& E1, + TopoDS_Edge& E2, + TopoDS_Face& F) +{ + Standard_Real f1,f2,l1,l2; + gp_Pnt2d P1,P2; + TopoDS_Shape aLocalF = F.Oriented(TopAbs_FORWARD); + TopoDS_Face FF = TopoDS::Face(aLocalF); + Handle(Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(E1,FF,f1,l1); + Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(E2,FF,f2,l2); + if (E1.Orientation () == TopAbs_FORWARD) P1 = C1->Value(f1); + else P1 = C1->Value(l1); + + if (E2.Orientation () == TopAbs_FORWARD) P2 = C2->Value(l2); + else P2 = C2->Value(f2); + Standard_Real Tol = 100*BRep_Tool::Tolerance(V); + Standard_Real Dist = P1.Distance(P2); + return Dist < Tol; +} + +//======================================================================= +//function : PurgeNewEdges +//purpose : +//======================================================================= +static void PurgeNewEdges(TopTools_ListOfShape& ConstEdges, + const TopTools_MapOfOrientedShape& UsedEdges) +{ + TopTools_ListIteratorOfListOfShape it(ConstEdges); + while ( it.More()) { + const TopoDS_Shape& NE = it.Value(); + if (!UsedEdges.Contains(NE)) { + ConstEdges.Remove(it); + } + else { + it.Next(); + } + } +} + +//======================================================================= +//function : StoreInMVE +//purpose : +//======================================================================= +static void StoreInMVE (const TopoDS_Face& F, + TopoDS_Edge& E, + TopTools_DataMapOfShapeListOfShape& MVE ) + +{ + TopoDS_Vertex V1, V2; + TopTools_ListOfShape Empty; + + TopExp::Vertices(E,V1,V2); + if (!MVE.IsBound(V1)) { + MVE.Bind(V1,Empty); + } + MVE(V1).Append(E); + + if (!MVE.IsBound(V2)) { + MVE.Bind(V2,Empty); + } + MVE(V2).Append(E); +} + +//======================================================================= +//function : Perform +//purpose : +//======================================================================= +void Partition_Loop::Perform() +{ + + TopTools_DataMapOfShapeListOfShape MVE; + TopTools_DataMapIteratorOfDataMapOfShapeListOfShape Mapit, Mapit1; + TopTools_ListIteratorOfListOfShape itl; + TopoDS_Vertex V1,V2; + + //----------------------------------- + // Construction map vertex => edges + //----------------------------------- + for (itl.Initialize(myConstEdges); itl.More(); itl.Next()) { + TopoDS_Edge& E = TopoDS::Edge(itl.Value()); + StoreInMVE(myFace,E,MVE); + } + + //---------------------------------------------- + // Construction of all the wires and of all the new faces. + //---------------------------------------------- + TopTools_MapOfOrientedShape UsedEdges; + + while (!MVE.IsEmpty()) { + TopoDS_Vertex VF,CV; + TopoDS_Edge CE,NE,EF; + TopoDS_Wire NW; + BRep_Builder B; + Standard_Boolean End= Standard_False; + + B.MakeWire(NW); + //-------------------------------- + // EF first edge. + //-------------------------------- + Mapit.Initialize(MVE); + EF = CE = TopoDS::Edge(Mapit.Value().First()); + + TopExp::Vertices(CE,V1,V2); + //-------------------------------- + // VF first vertex + //-------------------------------- + if (CE.Orientation() == TopAbs_FORWARD) { + CV = VF = V1; + } + else { + CV = VF = V2; + } + if (!MVE.IsBound(CV)) continue; + for ( itl.Initialize(MVE(CV)); itl.More(); itl.Next()) { + if (itl.Value().IsEqual(CE)) { + MVE(CV).Remove(itl); + break; + } + } + + int i = 0; + while (!End) { + //------------------------------- + // Construction of a wire. + //------------------------------- + TopExp::Vertices(CE,V1,V2); + if (!CV.IsSame(V1)) CV = V1; else CV = V2; + B.Add (NW,CE); + UsedEdges.Add(CE); + + //-------------- + // stop test + //-------------- + if (!MVE.IsBound(CV) || MVE(CV).IsEmpty() || CV.IsSame(VF) ) { + if (CV.IsSame(VF)) { + if (MVE(CV).Extent() == 1 ) MVE.UnBind(CV); + else { + for ( itl.Initialize(MVE(CV)); itl.More(); itl.Next()) { + if (itl.Value().IsEqual(CE)) { + MVE(CV).Remove(itl); + break; + } + } + } + } + End=Standard_True; + } + + //-------------- + // select edge + //-------------- + else { + Standard_Boolean find = SelectEdge(myFace,CE,CV,NE,MVE(CV)); + if (find) { + CE=NE; + if (MVE(CV).IsEmpty()) MVE.UnBind(CV); + if (CE.IsNull() ) { + MESSAGE ( " CE is NULL !!! " ) + End=Standard_True; + } + } + else { + MESSAGE ( " edge doesn't exist " ) + End=Standard_True; + } + } + } + + //----------------------------- + // Test if the wire is closed + //----------------------------- + if (VF.IsSame(CV) && SamePnt2d(VF,EF,CE,myFace)) { + } + else{ + MESSAGE ( "wire not closed" ) + } + myNewWires.Append (NW); + } + + PurgeNewEdges(myConstEdges,UsedEdges); + +} + + +//======================================================================= +//function : NewWires +//purpose : +//======================================================================= +const TopTools_ListOfShape& Partition_Loop::NewWires() const +{ + return myNewWires; +} + +//======================================================================= +//function : NewFaces +//purpose : +//======================================================================= +const TopTools_ListOfShape& Partition_Loop::NewFaces() const +{ + return myNewFaces; +} + +//======================================================================= +//function : WiresToFaces +//purpose : +//======================================================================= +void Partition_Loop::WiresToFaces() +{ + if (!myNewWires.IsEmpty()) { + BRepAlgo_FaceRestrictor FR; + + TopAbs_Orientation OriF = myFace.Orientation(); + TopoDS_Shape aLocalS = myFace.Oriented(TopAbs_FORWARD); + + FR.Init (TopoDS::Face(aLocalS),Standard_False); + TopTools_ListIteratorOfListOfShape it(myNewWires); + for (; it.More(); it.Next()) { + FR.Add(TopoDS::Wire(it.Value())); + } + + FR.Perform(); + + if (FR.IsDone()) { + for (; FR.More(); FR.Next()) { + myNewFaces.Append(FR.Current().Oriented(OriF)); + } + } + } +} diff --git a/PARTITION/Partition_Loop.hxx b/PARTITION/Partition_Loop.hxx new file mode 100644 index 000000000..9e9226d9d --- /dev/null +++ b/PARTITION/Partition_Loop.hxx @@ -0,0 +1,118 @@ +// 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 +// +// +// +// File : Partition_Loop.hxx +// Module : GEOM + +#ifndef _Partition_Loop_HeaderFile +#define _Partition_Loop_HeaderFile + +#ifndef _TopoDS_Face_HeaderFile +#include +#endif +#ifndef _TopTools_ListOfShape_HeaderFile +#include +#endif +#ifndef _TopTools_DataMapOfShapeListOfShape_HeaderFile +#include +#endif +class TopoDS_Face; +class TopoDS_Edge; +class TopTools_ListOfShape; + + +#ifndef _Standard_HeaderFile +#include +#endif +#ifndef _Standard_Macro_HeaderFile +#include +#endif + +class Partition_Loop { + +public: + + inline void* operator new(size_t,void* anAddress) + { + return anAddress; + } + inline void* operator new(size_t size) + { + return Standard::Allocate(size); + } + inline void operator delete(void *anAddress) + { + if (anAddress) Standard::Free((Standard_Address&)anAddress); + } +// inline void operator delete(void *anAddress, size_t size) +// { +// if (anAddress) Standard::Free((Standard_Address&)anAddress,size); +// } + // Methods PUBLIC + // +Standard_EXPORT Partition_Loop(); +Standard_EXPORT void Init(const TopoDS_Face& F) ; +Standard_EXPORT void AddConstEdge(const TopoDS_Edge& E) ; +Standard_EXPORT void Perform() ; +Standard_EXPORT const TopTools_ListOfShape& NewWires() const; +Standard_EXPORT void WiresToFaces() ; +Standard_EXPORT const TopTools_ListOfShape& NewFaces() const; + + + + +protected: + + // Methods PROTECTED + // + + + // Fields PROTECTED + // + + +private: + + // Methods PRIVATE + // + + + // Fields PRIVATE + // +TopoDS_Face myFace; +TopTools_ListOfShape myConstEdges; +TopTools_ListOfShape myNewWires; +TopTools_ListOfShape myNewFaces; + + +}; + + + + + +// other inline functions and methods (like "C++: function call" methods) +// + + +#endif diff --git a/PARTITION/Partition_Loop.ixx b/PARTITION/Partition_Loop.ixx new file mode 100644 index 000000000..1c40e7254 --- /dev/null +++ b/PARTITION/Partition_Loop.ixx @@ -0,0 +1,31 @@ +// 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 +// +// +// +// File : Partition_Loop.ixx +// Module : GEOM + +#include "Partition_Loop.jxx" + + + + diff --git a/PARTITION/Partition_Loop.jxx b/PARTITION/Partition_Loop.jxx new file mode 100644 index 000000000..dd86f05c3 --- /dev/null +++ b/PARTITION/Partition_Loop.jxx @@ -0,0 +1,41 @@ +// 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 +// +// +// +// File : Partition_Loop.jxx +// Module : GEOM + +#ifndef _TopoDS_Face_HeaderFile +#include +#endif +#ifndef _TopoDS_Edge_HeaderFile +#include +#endif +#ifndef _TopTools_ListOfShape_HeaderFile +#include +#endif +#ifndef _TopTools_DataMapOfShapeShape_HeaderFile +#include +#endif +#ifndef _Partition_Loop_HeaderFile +#include "Partition_Loop.hxx" +#endif diff --git a/PARTITION/Partition_Loop2d.cdl b/PARTITION/Partition_Loop2d.cdl new file mode 100644 index 000000000..7a6656e76 --- /dev/null +++ b/PARTITION/Partition_Loop2d.cdl @@ -0,0 +1,83 @@ +-- GEOM PARTITION : partition algorithm +-- +-- Copyright (C) 2003 CEA/DEN, EDF R&D +-- +-- +-- +-- File : Partition_Loop2d.cdl +-- Author : Benedicte MARTIN +-- Module : GEOM + +class Loop2d from Partition + + ---Purpose: Builds the loops from a set of edges on a face. + -- It works in supposition that all constant edges + -- are split edges of an initialization face and all + -- section edges are new on the face + +uses + + Orientation from TopAbs, + Boolean from Standard, + Face from TopoDS, + Image from BRepAlgo, + Face from TopoDS, + Edge from TopoDS, + ListOfShape from TopTools, + DataMapOfShapeListOfShape from TopTools, + MapOfShape from TopTools +is + + Create; + + Init (me : in out; F : Face from TopoDS) + ---Purpose: Init with the set of edges must have + -- pcurves on . + is static; + + AddConstEdge (me : in out; E : Edge from TopoDS) + ---Purpose: Add as unique edge in the result. + is static; + + AddSectionEdge (me : in out; E : Edge from TopoDS) + ---Purpose: Add as double edge in the result. + is static; + + Perform(me : in out) + ---Purpose: Make loops. + is static; + + NewWires (me) + ---Purpose: Returns the list of wires performed. + -- can be an empty list. + ---C++: return const & + returns ListOfShape from TopTools; + + WiresToFaces (me : in out; EdgeImage : Image from BRepAlgo) + ---Purpose: Build faces from the wires result. + -- serves to find original edge by new + -- one. + is static; + + NewFaces (me) + ---Purpose: Returns the list of faces. + ---Warning: The method as to be called before. + -- can be an empty list. + ---C++: return const & + returns ListOfShape from TopTools; + + +fields + + myFace : Face from TopoDS; + myFaceOri : Orientation from TopAbs; + myConstEdges : ListOfShape from TopTools; + myNewWires : ListOfShape from TopTools; + myNewFaces : ListOfShape from TopTools; + + -- internal wires do not contain constant edges + myInternalWL : ListOfShape from TopTools; + + mySectionEdges : MapOfShape from TopTools; + +end Loop2d; diff --git a/PARTITION/Partition_Loop2d.cxx b/PARTITION/Partition_Loop2d.cxx new file mode 100644 index 000000000..1e0a25787 --- /dev/null +++ b/PARTITION/Partition_Loop2d.cxx @@ -0,0 +1,1105 @@ +// GEOM PARTITION : partition algorithm +// +// Copyright (C) 2003 CEA/DEN, EDF R&D +// +// +// +// File : Partition_Loop2d.cxx +// Author : Benedicte MARTIN +// Module : GEOM +// $Header$ + +using namespace std; +#include "Partition_Loop2d.ixx" + +#include "utilities.h" +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//======================================================================= +//function : Partition_Loop2d +//purpose : +//======================================================================= + +Partition_Loop2d::Partition_Loop2d() +{ +} + +//======================================================================= +//function : Init +//purpose : Init with the set of edges must have +// pcurves on . +//======================================================================= + +void Partition_Loop2d::Init(const TopoDS_Face& F) +{ + myConstEdges.Clear(); + myNewWires .Clear(); + myNewFaces .Clear(); + myFace = F; + myFaceOri = myFace.Orientation(); + myFace.Orientation( TopAbs_FORWARD ); +} + +//======================================================================= +//function : AddConstEdge +//purpose : Add as unique edge in the result. +//======================================================================= + +void Partition_Loop2d::AddConstEdge (const TopoDS_Edge& E) +{ +#ifdef DEB + Standard_Real f,l; + Handle(Geom2d_Curve) pc = BRep_Tool::CurveOnSurface( E, myFace, f,l); + if (pc.IsNull()) { + INFOS( "AddConstEdge(): EDGE W/O PCURVE on FACE"); + } else +#endif + { + myConstEdges.Append(E); + } +} + +void Partition_Loop2d::AddSectionEdge (const TopoDS_Edge& E) +{ +#ifdef DEB + Standard_Real f,l; + Handle(Geom2d_Curve) pc = BRep_Tool::CurveOnSurface( E, myFace, f,l); + if (pc.IsNull()) + pc = BRep_Tool::CurveOnSurface( E, myFace, f,l); + gp_Vec2d Tg1; + gp_Pnt2d PC; + pc->D1(0.5*(f+l), PC, Tg1); + if (Tg1.Magnitude() <= gp::Resolution()) { + MESSAGE (""); + } + if (pc.IsNull()) { + INFOS( "AddConstEdge(): EDGE W/O PCURVE on FACE"); + } else +#endif + { + myConstEdges.Append(E); + myConstEdges.Append(E.Reversed()); + mySectionEdges.Add( E ); + } +} + +//======================================================================= +//function : SelectEdge +//purpose : Find the edge connected by the vertex in the list . +// Is erased of the list. If is too in the list +// with the same orientation, it's erased of the list +//======================================================================= + +static Standard_Boolean SelectEdge(const BRepAdaptor_Surface& Surf, + const TopoDS_Edge& CE, + const TopoDS_Vertex& CV, + TopoDS_Edge& NE, + const TopTools_ListOfShape& LE) +{ + NE.Nullify(); + + if (LE.Extent() > 1) { + //-------------------------------------------------------------- + // Several possible edges. + // - Test the edges differents of CE + //-------------------------------------------------------------- + TopoDS_Face FForward = Surf.Face(); + + 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_Pnt2d PC, P; + gp_Pnt P3d; + + Cc->D1(uc, PC, CTg1); + if (CE.Orientation () == TopAbs_REVERSED) CTg1.Reverse(); + + Standard_Real anglemin = 3 * PI; +// Standard_Real sqdist, sqdistmin = 1.0e50; + + TopTools_ListIteratorOfListOfShape itl; + for ( itl.Initialize(LE); itl.More(); itl.Next()) { + const TopoDS_Edge& E = TopoDS::Edge(itl.Value()); + if (E.IsSame(CE)) + continue; + if (! CV.IsSame( TopExp::FirstVertex( E, Standard_True ))) + continue; + + C = BRep_Tool::CurveOnSurface(E,FForward,f,l); + if (E.Orientation () == TopAbs_FORWARD) u = f + du; + else u = l - du; + + C->D1(u, P, Tg1); +// if (P.SquareDistance(PC); > tol2d2) +// continue; + + if (E.Orientation () == TopAbs_REVERSED) Tg1.Reverse(); + + Standard_Real angle = Tg1.Angle(CTg1); + + 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 + } + } +#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; + } +#endif + } + else if (LE.Extent() == 1) { + NE = TopoDS::Edge(LE.First()); + } + else { + return Standard_False; + } + return !NE.IsNull(); +} + +//======================================================================= +//function : SamePnt2d +//purpose : +//======================================================================= + +static Standard_Boolean SamePnt2d(const TopoDS_Vertex& V1, + 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); + Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(E2,F,f2,l2); + + gp_Pnt2d P1 = C1->Value( BRep_Tool::Parameter(V1,E1)); + gp_Pnt2d P2 = C2->Value( BRep_Tool::Parameter(V2,E2)); + + Standard_Real Tol = 100 * BRep_Tool::Tolerance(V1); + Standard_Real Dist = P1.Distance(P2); + return Dist < Tol; +} + + +//======================================================================= +//function : StoreInMVE +//purpose : +//======================================================================= + +static void StoreInMVE (const TopoDS_Face& /*F*/, + TopoDS_Edge& E, + TopTools_DataMapOfShapeListOfShape& MVE ) + +{ + TopoDS_Vertex V1, V2; + TopTools_ListOfShape Empty; + + TopExp::Vertices(E,V1,V2); + if (!MVE.IsBound(V1)) { + MVE.Bind(V1,Empty); + } + MVE(V1).Append(E); + + if (!MVE.IsBound(V2)) { + MVE.Bind(V2,Empty); + } + MVE(V2).Append(E); +} + +//======================================================================= +//function : RemoveFromMVE +//purpose : +//======================================================================= + +static void RemoveFromMVE(const TopoDS_Edge& E, + TopTools_DataMapOfShapeListOfShape& MVE) +{ + TopTools_ListIteratorOfListOfShape itl; + TopoDS_Vertex V1,V2; + TopExp::Vertices (E,V1,V2); + if (MVE.IsBound(V1)) + for ( itl.Initialize(MVE(V1)); itl.More(); itl.Next()) { + if (itl.Value().IsEqual(E)) { + 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; + } + } +} +//======================================================================= +//function : addConnected +//purpose : add to all edges reachable from +//======================================================================= + +static void addConnected(const TopoDS_Shape& E, + 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 ); + } + } +} +//======================================================================= +//function : canPassToOld +//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; +} + +//======================================================================= +//function : MakeDegenAndSelect +//purpose : Find parameter of intersection of with and +// select an edge with its parameter closest to found one. +// Return new degenerated edge trimming by found parameters +//======================================================================= + +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) +{ + if (EdgesSeq.Length() < 3) { + if (CE == EdgesSeq.First()) + NE = TopoDS::Edge( EdgesSeq.Last() ); + else + NE = TopoDS::Edge( EdgesSeq.First() ); + return DE; + } + + // find parameter on DE where it intersects CE + + Standard_Real U1; + Standard_Integer i, nb = EdgesSeq.Length(); + for (i=1; i<= nb; ++i) { + if (CE == EdgesSeq(i)) { + U1 = USeq(i); + break; + } + } + + // select NE with param closest to U1 thus finding U2 for a new degen edge + + Standard_Real U2, dU, dUmin = 1.e100; + Standard_Boolean isReversed = ( DE.Orientation() == TopAbs_REVERSED ); + for (i=1; i<= nb; ++i) { + dU = USeq(i) - U1; + if (isReversed ? (dU > 0) : (dU < 0)) + continue; + dU = Abs( dU ); + if ( dU > dUmin || IsEqual( dU, 0.)) + continue; + const TopoDS_Edge& E = TopoDS::Edge ( EdgesSeq(i) ); + if ( ! CV.IsSame( TopExp::FirstVertex( E , Standard_True ))) + continue; + NE = E; + dUmin = dU + Epsilon(dU); + U2 = USeq(i); + } + + // make a new degenerated edge + TopoDS_Edge NewDegen = TopoDS::Edge ( DE.EmptyCopied() ); + + Standard_Real Tol = BRep_Tool::Tolerance( CV ); + TopoDS_Vertex V = CV; + + BRep_Builder B; + V.Orientation( NewDegen.Orientation() ); + B.UpdateVertex( V, U1, NewDegen, Tol); + B.Add ( NewDegen , V ); + + V.Reverse(); + B.UpdateVertex( V, U2, NewDegen, Tol); + B.Add ( NewDegen , V ); + + return NewDegen; +} + +//======================================================================= +//function : prepareDegen +//purpose : Intersect with edges bound to its vertex in +// and store intersection parameter on in +// as well as the edges them-self in . +// Bind to vertex of in +//======================================================================= + +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_Vertex& V = TopExp::FirstVertex ( DegEdge ); + MVDEI.Bind ( V, DegEdgeIndex ); + + const TopTools_ListOfShape& EdgesList = MVE ( V ); + // if only 2 edges come to degenerated one, no pb in selection and + // no need to intersect them, just simulate asked data + Standard_Boolean doIntersect = ( EdgesList.Extent() > 2 ); + + BRepAdaptor_Curve2d DC, C; + Geom2dInt_GInter InterCC; + Standard_Real Tol = Precision::PConfusion(); + if ( doIntersect ) + DC.Initialize( DegEdge, F ); + + // avoid intersecting twice the same edge + BRepOffset_DataMapOfShapeReal EUMap ( EdgesList.Extent() ); + + Standard_Real U, f, l; + BRep_Tool::Range (DegEdge, f, l); + + TopTools_ListIteratorOfListOfShape itE (EdgesList); + for (; itE.More(); itE.Next()) { + + const TopoDS_Edge& E = TopoDS::Edge ( itE.Value() ); + + if ( !doIntersect) { + U = 0.; // it won't be used + } + else if ( BRep_Tool::IsClosed( E, F )) { + // seam edge: select U among f and l + Standard_Boolean first = Standard_True; + if ( V.IsSame ( TopExp::FirstVertex( E, Standard_True ) )) + first = Standard_False; + if ( DegEdge.Orientation() == TopAbs_REVERSED ) + first = !first; + U = first ? f : l; + } + else if ( EUMap.IsBound( E ) ) { + // same edge already bound + U = EUMap( E ); + } + else { + // intersect 2d curves + C.Initialize( E, F ); + InterCC.Perform ( DC, C , Tol, Tol ); + if (! InterCC.IsDone() || InterCC.NbPoints() == 0) { + MESSAGE ( "NO 2d INTERSECTION ON DEGENERATED EDGE" ); + continue; + } + // hope there is only one point of intersection + U = InterCC.Point( 1 ).ParamOnFirst(); + } + USeq.Append ( U ); + EdgesSeq.Append ( E ); + } +} +//======================================================================= +//function : Perform +//purpose : Make loops. +//======================================================================= + +void Partition_Loop2d::Perform() +{ + + Standard_Integer NbConstEdges = myConstEdges.Extent(); + TopTools_DataMapOfShapeListOfShape MVE(NbConstEdges) , MVE2(NbConstEdges); + TopTools_DataMapIteratorOfDataMapOfShapeListOfShape Mapit; + TopTools_ListIteratorOfListOfShape itl; + TopoDS_Vertex V1,V2; + BRepAdaptor_Surface Surface ( myFace, Standard_False ); + + // degenerated edges and parameters of their 2d intersection with other edges + TopoDS_Edge DE [2]; + TopTools_SequenceOfShape SEID [2]; // seq of edges intersecting degenerated + TColStd_SequenceOfReal SeqU [2]; // n-th U corresponds to n-th edge in SEID + TopTools_DataMapOfShapeInteger MVDEI(2); // map vertex - degenerated edge index + Standard_Integer iDeg = 0; // index of degenerated edge [0,1] + + //--------------------------------------------------------- + // Construction map vertex => edges, find degenerated edges + //--------------------------------------------------------- + for (itl.Initialize(myConstEdges); itl.More(); itl.Next()) { + TopoDS_Edge& E = TopoDS::Edge(itl.Value()); + if ( BRep_Tool::Degenerated( E )) { + if (DE[0].IsNull()) DE[0] = E; + else DE[1] = E; + } + else + StoreInMVE(myFace,E,MVE); + } + + // fill data for degenerated edges + if ( ! DE[0].IsNull() ) + prepareDegen ( DE[0], myFace, MVE, SEID[0], SeqU[0], MVDEI, 0); + if ( ! DE[1].IsNull() ) + prepareDegen ( DE[1], myFace, MVE, SEID[1], SeqU[1], MVDEI, 1); + + + // to detect internal wires + Standard_Boolean isInternCW = 0; + MVE2 = MVE; + + + //------------------------------ + // Construction of all the wires + //------------------------------ + // first, we collect wire edges in WEL list looking for same edges that + // will be then removed possibly exploding a wire into parts; + // second, build wire(s) + + while (!MVE.IsEmpty()) { + + TopoDS_Vertex VF,CV; + TopoDS_Edge CE,NE,EF; + TopoDS_Wire NW; + BRep_Builder B; + Standard_Boolean End = Standard_False; + TopTools_ListOfShape WEL; + + Mapit.Initialize(MVE); + if (Mapit.Value().IsEmpty()) { + MVE.UnBind(Mapit.Key()); + continue; + } + + // EF first edge. + EF = CE = TopoDS::Edge(Mapit.Value().First()); + // VF first vertex + VF = TopExp::FirstVertex( CE, Standard_True); + + isInternCW = Standard_True; + + TopTools_MapOfShape addedEM (NbConstEdges); // map of edges added to WEL + TopTools_MapOfShape doubleEM (NbConstEdges); // edges encountered twice in WEL + + //------------------------------- + // Construction of a wire. + //------------------------------- + while (!End) { + + // 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 ); + else { + doubleEM.Add( CE ); + RemoveFromMVE (CE,MVE2); + TopoDS_Edge CERev = CE; + CERev.Reverse(); + RemoveFromMVE (CERev,MVE2); + } + + RemoveFromMVE (CE,MVE); + + CV = TopExp::LastVertex( CE, Standard_True); + + if (isInternCW && !mySectionEdges.Contains(CE)) + // 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 ); + CE = NE; + End = CV.IsSame( VF ); + continue; + } + + //-------------- + // stop test + //-------------- + if (MVE(CV).IsEmpty()) { + End=Standard_True; + MVE.UnBind(CV); + } + else if (CV.IsSame(VF) && SamePnt2d(CV,CE, VF,EF, myFace) ) { + 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; + } + } // 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()); + 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(); + } + if ( WEL.IsEmpty()) + 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-- ); + } + } + } + // 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 ); + 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) { + NE = TopoDS::Edge( itl.Value() ); + if ( CV.IsSame( TopExp::FirstVertex( NE, Standard_True ))) { + WEL.Remove( itl ); + 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 ); + } + } // 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 ) { + 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() )) + addConnected (itl.Value(), outerEM, visitedVM, MVE2); + } + // if an edge of a wire is in , the wire is not internal + TopExp_Explorer expIWE; + TopTools_ListIteratorOfListOfShape itIW ( myInternalWL ); + while (itIW.More()) { + expIWE.Init ( itIW.Value() , TopAbs_EDGE ); + if ( outerEM.Contains( expIWE.Current() )) { + myNewWires.Append ( itIW.Value() ); + myInternalWL.Remove( itIW ); // == itIW.Next() + } + else + itIW.Next(); + } + } +} +//======================================================================= +//function : isHole +//purpose : +//======================================================================= + +static Standard_Boolean isHole (const TopoDS_Wire& W, + 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()); + return (classif.PerformInfinitePoint() == TopAbs_IN); +} + +//======================================================================= +//function : IsInside +//purpose : check if W1 is inside W2. Suppose W2 is not a hole !!!! +//======================================================================= + +static Standard_Boolean isInside(const TopoDS_Face& F, + const TopoDS_Wire& W1, + const TopoDS_Wire& W2) +{ + // make a face with wire W2 + BRep_Builder B; + TopoDS_Shape aLocalShape = F.EmptyCopied(); + TopoDS_Face newFace = TopoDS::Face(aLocalShape); + B.Add(newFace,W2); + + // get any 2d point of W1 + TopExp_Explorer exp(W1,TopAbs_EDGE); + const TopoDS_Edge& edg = 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)); + + BRepTopAdaptor_FClass2d classif(newFace,Precision::PConfusion()); + return (classif.Perform(pt2d) == TopAbs_IN); +} + +//======================================================================= +//function : NewWires +//purpose : Returns the list of wires performed. +// can be an empty list. +//======================================================================= + +const TopTools_ListOfShape& Partition_Loop2d::NewWires() const +{ + return myNewWires; +} + +//======================================================================= +//function : NewFaces +//purpose : Returns the list of faces. +//Warning : The method as to be called before. +// can be an empty list. +//======================================================================= + +const TopTools_ListOfShape& Partition_Loop2d::NewFaces() const +{ + return myNewFaces; +} + +//======================================================================= +//function : findEqual +//purpose : move wires form to pairs of wires build of the same edges +//======================================================================= + +static void findEqual (TopTools_ListOfShape& WL, + TopTools_DataMapOfShapeShape& EqWM, + const TopoDS_Face& F) +{ + TopTools_ListIteratorOfListOfShape it1, it2; + Standard_Integer i,j; + TColStd_MapOfInteger IndMap; + for (it1.Initialize(WL), i=1; it1.More(); it1.Next(), i++) { + + 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; + + TopTools_IndexedMapOfShape EdgesMap; + TopExp::MapShapes (Wire1, TopAbs_EDGE, EdgesMap); + + const TopoDS_Shape& Wire2 = it2.Value(); + TopoDS_Iterator itE ( Wire2); + for (; itE.More(); itE.Next()) { + 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; + } + } + } + // clear WL + it1.Initialize(WL); + i=1; + while (it1.More()) { + if (IndMap.Contains(i)) + WL.Remove(it1); // next node becomes current and with Next() we would miss it + else + it1.Next(); + i++; + } +} + +//======================================================================= +//function : classify +//purpose : bind to a wire a list of internal wires +//======================================================================= + +static void classify(const TopTools_DataMapOfShapeShape& EqWM, + 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; + 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); + else if (isInside(F, Wire2, Wire1)) + OuterInner.Add (Wire1, Wire2); + } + } +} +//======================================================================= +//function : WiresToFaces +//purpose : Build faces from the wires result. +// serves to find original edge by new +// one.
contains edges resulting from face +// intersections +//======================================================================= + +//#define USE_BREPFEAT_SPLITSHAPE + +#ifdef USE_BREPFEAT_SPLITSHAPE + +# include +void Partition_Loop2d::WiresToFaces(const BRepAlgo_Image& EdgeImage) +#else + +# include +void Partition_Loop2d::WiresToFaces(const BRepAlgo_Image& ) +#endif +{ + Standard_Integer nbW = myNewWires.Extent() + myInternalWL.Extent(); + if (nbW==0) + return; + +#ifndef USE_BREPFEAT_SPLITSHAPE + + // ============================================================ + // use BRepAlgo_FaceRestrictor to make faces + // ============================================================ + + BRepAlgo_FaceRestrictor FR; + FR.Init (myFace,Standard_False); + + // FaceRestrictor is instable in rather simple cases + // (ex. a single face of bellecoque.brep splited by 10 planes: + // 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); + if ( itOldW.More()) { + const TopoDS_Wire& FirstOldWire = TopoDS::Wire( itOldW.Value() ); + itOldW.Next(); + hasOldHoles = itOldW.More() || isHole( FirstOldWire, myFace); + } + if (myInternalWL.IsEmpty() && !hasOldHoles) { + // each wire bounds one face + BRep_Builder B; + TopTools_ListIteratorOfListOfShape itNW (myNewWires); + for (; itNW.More(); itNW.Next()) { + TopoDS_Face NF = TopoDS::Face ( myFace.EmptyCopied() ); + B.Add ( NF, itNW.Value() ); + NF.Orientation( myFaceOri); + myNewFaces.Append ( NF ); + } + 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 + // hole in a face and should come together with outer wires of face. + // The other of a wires pair bounds a face that may have holes in turn. + + // Find equal wires among internal wires + TopTools_DataMapOfShapeShape EqWM; // key is a hole part of a pair of equal wires + findEqual (myInternalWL, EqWM, myFace); + + if (!EqWM.IsEmpty()) { // there are equal wires + + 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); + + // make face of most internal of equal wires and its inner wires + while ( !EqWM.IsEmpty()) { + + TopTools_ListOfShape prevHolesL; // list of hole-part of previous most internal equal wires + + // find most internal wires among pairs (key - hole, value - outer part) + TopTools_DataMapIteratorOfDataMapOfShapeShape it(EqWM); + for ( ; it.More(); it.Next()) { + + TopoDS_Wire outerW = TopoDS::Wire ( it.Value() ); + if ( OuterInner.HasDescendant( outerW ) && // has internal + ! OuterInner.Descendant( outerW ).IsEmpty() ) + continue; + + 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(); + } + + // 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()); + } + + FR.Clear(); + + // add hole-parts to FaceRestrictor, + // remove themfrom 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 ); + } + + } // while (!EqWM.IsEmpty) + + } // !EqWM.IsEmpty() + + myNewWires.Append ( myInternalWL ); + + TopTools_ListIteratorOfListOfShape itW (myNewWires); + for (; itW.More(); itW.Next()) { + TopoDS_Wire& W = TopoDS::Wire ( itW.Value() ); + FR.Add(W); + } + FR.Perform(); + for (; FR.IsDone() && FR.More(); FR.Next()) + 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()) + itNF.Value().Orientation( myFaceOri ); +} diff --git a/PARTITION/Partition_Loop2d.hxx b/PARTITION/Partition_Loop2d.hxx new file mode 100644 index 000000000..2310e1581 --- /dev/null +++ b/PARTITION/Partition_Loop2d.hxx @@ -0,0 +1,106 @@ +// GEOM PARTITION : partition algorithm +// +// Copyright (C) 2003 CEA/DEN, EDF R&D +// +// +// +// File : Partition_Loop2d.hxx +// Module : GEOM + +#ifndef _Partition_Loop2d_HeaderFile +#define _Partition_Loop2d_HeaderFile + +#ifndef _TopoDS_Face_HeaderFile +#include +#endif +#ifndef _TopAbs_Orientation_HeaderFile +#include +#endif +#ifndef _TopTools_ListOfShape_HeaderFile +#include +#endif +#ifndef _TopTools_MapOfShape_HeaderFile +#include +#endif +class TopoDS_Face; +class TopoDS_Edge; +class TopTools_ListOfShape; +class BRepAlgo_Image; + + +#ifndef _Standard_HeaderFile +#include +#endif +#ifndef _Standard_Macro_HeaderFile +#include +#endif + +class Partition_Loop2d { + +public: + + void* operator new(size_t,void* anAddress) + { + return anAddress; + } + void* operator new(size_t size) + { + return Standard::Allocate(size); + } + void operator delete(void *anAddress) + { + if (anAddress) Standard::Free((Standard_Address&)anAddress); + } + // Methods PUBLIC + // +Standard_EXPORT Partition_Loop2d(); +Standard_EXPORT void Init(const TopoDS_Face& F) ; +Standard_EXPORT void AddConstEdge(const TopoDS_Edge& E) ; +Standard_EXPORT void AddSectionEdge(const TopoDS_Edge& E) ; +Standard_EXPORT void Perform() ; +Standard_EXPORT const TopTools_ListOfShape& NewWires() const; +Standard_EXPORT void WiresToFaces(const BRepAlgo_Image& EdgeImage) ; +Standard_EXPORT const TopTools_ListOfShape& NewFaces() const; + + + + + +protected: + + // Methods PROTECTED + // + + + // Fields PROTECTED + // + + +private: + + // Methods PRIVATE + // + + + // Fields PRIVATE + // +TopoDS_Face myFace; +TopAbs_Orientation myFaceOri; +TopTools_ListOfShape myConstEdges; +TopTools_ListOfShape myNewWires; +TopTools_ListOfShape myNewFaces; +TopTools_ListOfShape myInternalWL; +TopTools_MapOfShape mySectionEdges; + + +}; + + + + + +// other Inline functions and methods (like "C++: function call" methods) +// + + +#endif diff --git a/PARTITION/Partition_Loop2d.ixx b/PARTITION/Partition_Loop2d.ixx new file mode 100644 index 000000000..2d35fd5c7 --- /dev/null +++ b/PARTITION/Partition_Loop2d.ixx @@ -0,0 +1,14 @@ +// GEOM PARTITION : partition algorithm +// +// Copyright (C) 2003 CEA/DEN, EDF R&D +// +// +// +// File : Partition_Loop2d.ixx +// Module : GEOM + +#include "Partition_Loop2d.jxx" + + + + diff --git a/PARTITION/Partition_Loop2d.jxx b/PARTITION/Partition_Loop2d.jxx new file mode 100644 index 000000000..555c16c80 --- /dev/null +++ b/PARTITION/Partition_Loop2d.jxx @@ -0,0 +1,24 @@ +// GEOM PARTITION : partition algorithm +// +// Copyright (C) 2003 CEA/DEN, EDF R&D +// +// +// +// File : Partition_Loop2d.jxx +// Module : GEOM + +#ifndef _TopoDS_Face_HeaderFile +#include +#endif +#ifndef _TopoDS_Edge_HeaderFile +#include +#endif +#ifndef _TopTools_ListOfShape_HeaderFile +#include +#endif +#ifndef _BRepAlgo_Image_HeaderFile +#include +#endif +#ifndef _Partition_Loop2d_HeaderFile +#include "Partition_Loop2d.hxx" +#endif diff --git a/PARTITION/Partition_Loop3d.cdl b/PARTITION/Partition_Loop3d.cdl new file mode 100644 index 000000000..435fef6d5 --- /dev/null +++ b/PARTITION/Partition_Loop3d.cdl @@ -0,0 +1,69 @@ +-- GEOM PARTITION : partition algorithm +-- +-- Copyright (C) 2003 CEA/DEN, EDF R&D +-- +-- +-- +-- File : Partition_Loop3d.cdl +-- Module : GEOM + +class Loop3d from Partition + + ---Purpose: Builds the shells from a set of faces. + -- Provides methods for comparing faces mutual + -- location. + +uses + Vec from gp, + MapOfOrientedShape from TopTools, + IndexedDataMapOfShapeListOfShape from TopTools, + Face from TopoDS, + Edge from TopoDS, + ListOfShape from TopTools, + Shape from TopoDS + +is + + Create; + + AddConstFaces (me : in out; S : Shape from TopoDS) + ---Purpose: Add faces of as unique faces in the result. + is static; + + AddSectionFaces (me : in out; S : Shape from TopoDS) + ---Purpose: Add faces of as double faces in the result. + is static; + + MakeShells (me : in out; AvoidFacesMap : MapOfOrientedShape from TopTools) + returns ListOfShape from TopTools is static; + ---Purpose: Make and return shells. + -- can contain faces that must not be + -- added to result shells. + ---C++: return const & + + + ---Category: class methods + + IsInside (myclass; E : Edge from TopoDS; + F1, F2 : Face from TopoDS; + CountDot : Boolean from Standard; + Dot : in out Real from Standard; + GoodOri : in out Boolean from Standard) + returns Boolean from Standard; + ---Purpose: check if is inside by edge . + -- if , compute : scalar production of + -- normalized vectors pointing inside faces, and + -- check if faces are oriented well for sewing + + Normal (myclass; E : Edge from TopoDS; + F : Face from TopoDS) returns Vec from gp; + + +fields + + myNewShells : ListOfShape from TopTools; -- result + + myFaces : ListOfShape from TopTools; + myEFMap : IndexedDataMapOfShapeListOfShape from TopTools; + +end Loop3d; diff --git a/PARTITION/Partition_Loop3d.cxx b/PARTITION/Partition_Loop3d.cxx new file mode 100644 index 000000000..cb5ecff04 --- /dev/null +++ b/PARTITION/Partition_Loop3d.cxx @@ -0,0 +1,351 @@ +// GEOM PARTITION : partition algorithm +// +// Copyright (C) 2003 CEA/DEN, EDF R&D +// +// +// +// File : Partition_Loop3d.cxx +// Module : GEOM + +using namespace std; +#include "Partition_Loop3d.ixx" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//======================================================================= +//function : Partition_Loop3d +//purpose : +//======================================================================= + +Partition_Loop3d::Partition_Loop3d() +{ +} + +//======================================================================= +//function : AddConstFaces +//purpose : Add faces of as unique faces in the result. +//======================================================================= + +void Partition_Loop3d::AddConstFaces(const TopoDS_Shape& S) +{ + TopExp_Explorer FaceExp(S, TopAbs_FACE); + for (; FaceExp.More(); FaceExp.Next()) + myFaces.Append( FaceExp.Current() ); + + TopExp::MapShapesAndAncestors(S, TopAbs_EDGE, TopAbs_FACE, myEFMap); +} + +//======================================================================= +//function : AddSectionFaces +//purpose : Add faces of as double faces in the result. +//======================================================================= + +void Partition_Loop3d::AddSectionFaces(const TopoDS_Shape& S) +{ + AddConstFaces( S ); + AddConstFaces( S.Reversed() ); +} + +//======================================================================= +//function : MakeShells +//purpose : Make and return shells. +// can contain faces that must not be +// added to result shells. +//======================================================================= + +const TopTools_ListOfShape& + Partition_Loop3d::MakeShells (const TopTools_MapOfOrientedShape& AvoidFacesMap) +{ + myNewShells.Clear(); + + BRep_Builder Builder; + TopTools_MapOfShape CheckedEdgesMap; + TopTools_MapOfOrientedShape AddedFacesMap; + + TopTools_ListIteratorOfListOfShape itF (myFaces); + for (; itF.More(); itF.Next()) + { + const TopoDS_Shape& FF = itF.Value(); + if (AvoidFacesMap.Contains( FF ) || + ! AddedFacesMap.Add( FF ) ) + continue; + + // make a new shell + TopoDS_Shell Shell; + Builder.MakeShell(Shell); + Builder.Add(Shell,FF); + + // clear the maps from shapes added to previous Shell + TopTools_MapIteratorOfMapOfShape itEM (CheckedEdgesMap); + for (; itEM.More(); itEM.Next()) { + TopTools_ListOfShape& FL = myEFMap.ChangeFromKey( itEM.Key()); + TopTools_ListIteratorOfListOfShape it (FL); + while ( it.More()) { + if (AddedFacesMap.Contains( it.Value())) + FL.Remove( it ); + else + it.Next(); + } + } + CheckedEdgesMap.Clear(); + + + // loop on faces added to Shell; add their neighbor faces to Shell and so on + TopoDS_Iterator itAddedF (Shell); + for (; itAddedF.More(); itAddedF.Next()) + { + const TopoDS_Face& F = TopoDS::Face (itAddedF.Value()); + + // loop on edges of F; find a good neighbor face of F by E + TopExp_Explorer EdgeExp(F, TopAbs_EDGE); + for (; EdgeExp.More(); EdgeExp.Next()) + { + const TopoDS_Edge& E = TopoDS::Edge( EdgeExp.Current()); + if (! CheckedEdgesMap.Add( E )) + continue; + + // candidate faces list + const TopTools_ListOfShape& FL = myEFMap.ChangeFromKey(E); + if (FL.IsEmpty()) + continue; + // select one of neighbors + TopoDS_Face SelF; + if (FL.Extent() == 2) { + if (! F.IsSame( FL.First() )) + SelF = TopoDS::Face( FL.First() ); + else if (!F.IsSame( FL.Last() )) + SelF = TopoDS::Face( FL.Last() ); + } + else { + // check if a face already added to Shell shares E + TopTools_ListIteratorOfListOfShape it (FL); + Standard_Boolean found = Standard_False; + for (; !found && it.More(); it.Next()) + if (F != it.Value()) + found = AddedFacesMap.Contains( it.Value() ); + if (found) + continue; + // select basing on geometrical check + Standard_Boolean GoodOri, inside; + Standard_Real dot, MaxDot = -100; + TopTools_ListOfShape TangFL; // tangent faces + for ( it.Initialize( FL ) ; it.More(); it.Next()) { + const TopoDS_Face& NeighborF = TopoDS::Face( it.Value()); + if (NeighborF.IsSame( F )) + continue; + inside = Partition_Loop3d::IsInside( E, F, NeighborF, 1, dot, GoodOri); + if (!GoodOri) + continue; + if (!inside) + dot = -dot - 3; + if (dot < MaxDot) + continue; + if ( IsEqual( dot, MaxDot)) + TangFL.Append(SelF); + else + TangFL.Clear(); + MaxDot = dot; + SelF = NeighborF; + } + if (!TangFL.IsEmpty()) { + for (it.Initialize( TangFL ); it.More(); it.Next()) { + const TopoDS_Face& NeighborF = TopoDS::Face( it.Value()); + if (Partition_Loop3d:: IsInside( E, SelF , NeighborF, 0, dot, GoodOri)) + SelF = NeighborF; + } + } + } + if (!SelF.IsNull() && + AddedFacesMap.Add( SelF ) && + !AvoidFacesMap.Contains( SelF )) + Builder.Add( Shell, SelF); + + } // loop on edges of F + + } // loop on the faces added to Shell + + // Shell is complete + myNewShells.Append( Shell ); + + } // loop on myFaces + + + // prepare to the next call + myFaces.Clear(); + myEFMap.Clear(); + + return myNewShells; +} + + + +//======================================================================= +//function : Normal +//purpose : +//======================================================================= + +gp_Vec Partition_Loop3d::Normal(const TopoDS_Edge& E, + const TopoDS_Face& F) +{ + gp_Vec Norm, V1, V2; + Standard_Real First, Last; + gp_Pnt Ps; + + Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface (E, F, First, Last); + Handle(Geom_Surface) Sf = BRep_Tool::Surface(F); + + gp_Pnt2d p = C2d->Value( 0.5*(First+Last) ); + Sf->D1(p.X(), p.Y(), Ps, V1, V2); + Norm = V1.Crossed(V2); + + if (F.Orientation() == TopAbs_REVERSED ) + Norm.Reverse(); + + return Norm; +} + +//======================================================================= +//function : NextNormal +//purpose : find normal to F at point a little inside F near the middle of E +//warning : E must be properly oriented in F. +//======================================================================= + +static gp_Vec NextNormal(const TopoDS_Edge& E, + const TopoDS_Face& F) +{ + Standard_Real First, Last; + + Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface (E, F, First, Last); + Handle(Geom_Surface) Sf = BRep_Tool::Surface(F); + + gp_Pnt2d p; + gp_Vec2d v; + C2d->D1( 0.5*(First+Last), p, v); + if (E.Orientation() != F.Orientation()) + v.Reverse(); + gp_Dir2d dir( -v.Y(), v.X() ); // dir inside F + + Standard_Real duv = 1e-6; // this is not Ok and may give incorrect result if + // resolutionUV of compared faces is very different. To have a good result, + //it is necessary to get normal to faces at points equidistant from E in 3D + + p.SetX( p.X() + dir.X()*duv ); + p.SetY( p.Y() + dir.Y()*duv ); + + gp_Pnt Ps; + gp_Vec Norm, V1, V2, VV1, VV2; + Sf->D1( p.X(), p.Y(), Ps, V1, V2); + Norm = V1.Crossed(V2); + + if (F.Orientation() == TopAbs_REVERSED ) + Norm.Reverse(); + + return Norm; +} + + +//======================================================================= +//function : FindEinF +//purpose : find E in F +//======================================================================= + +static TopoDS_Edge FindEinF(const TopoDS_Edge& E, + const TopoDS_Face& F) +{ + TopExp_Explorer expl (F, TopAbs_EDGE); + for (; expl.More(); expl.Next()) + if( E.IsSame( expl.Current() )) + return TopoDS::Edge(expl.Current()); + TopoDS_Edge nullE; + return nullE; +} + +//======================================================================= +//function : IsInside +//purpose : check if is inside by edge . +// if , compute : scalar production of +// normalized vectors pointing inside faces, and +// check if faces are oriented well for sewing +//======================================================================= + +Standard_Boolean Partition_Loop3d::IsInside(const TopoDS_Edge& E, + const TopoDS_Face& F1, + const TopoDS_Face& F2, + const Standard_Boolean CountDot, + Standard_Real& Dot, + Standard_Boolean& GoodOri) +{ + Standard_Real f, l; + gp_Pnt P; + gp_Vec Vc1, Vc2, Vin1, Vin2, Nf1, Nf2; + Handle(Geom_Curve) Curve = BRep_Tool::Curve(E,f,l); + Curve->D1( 0.5*(f + l), P, Vc2); + TopoDS_Edge E1, E2 = FindEinF (E, F2); + if (E2.Orientation() == TopAbs_REVERSED ) Vc2.Reverse(); + + Nf1 = Normal(E,F1); + Nf2 = Normal(E,F2); + + Standard_Real sin = + Nf1.CrossSquareMagnitude(Nf2) / Nf1.SquareMagnitude() / Nf2.SquareMagnitude(); + Standard_Boolean tangent = sin < 0.001; + + Standard_Boolean inside = 0; + if (tangent) { + E1 = FindEinF (E, F1); + gp_Vec NNf1 = NextNormal(E1,F1); + gp_Vec NNf2 = NextNormal(E2,F2); + Vin2 = NNf2.Crossed(Vc2); + inside = Vin2 * NNf1 < 0; + } + else { + Vin2 = Nf2.Crossed(Vc2); + inside = Vin2 * Nf1 < 0; + } + + if (!CountDot) return inside; + + if (tangent) + Vin2 = Nf2.Crossed(Vc2); + else + E1 = FindEinF (E, F1); + + Vc1 = Vc2; + if (E1.Orientation() != E2.Orientation()) + Vc1.Reverse(); + Vin1 = Nf1.Crossed(Vc1); + + if (tangent) { + Standard_Real N1N2 = Nf1 * Nf2; + GoodOri = (Vin2 * Vin1 < 0) ? N1N2 > 0 : N1N2 < 0; + } + else { + Standard_Real V1N2 = Vin1 * Nf2; + GoodOri = ( inside ? V1N2 <= 0 : V1N2 >= 0); + } + + Vin1.Normalize(); + Vin2.Normalize(); + + Dot = Vin2 * Vin1; + + return inside; +} + diff --git a/PARTITION/Partition_Loop3d.hxx b/PARTITION/Partition_Loop3d.hxx new file mode 100644 index 000000000..b946b32df --- /dev/null +++ b/PARTITION/Partition_Loop3d.hxx @@ -0,0 +1,102 @@ +// GEOM PARTITION : partition algorithm +// +// Copyright (C) 2003 CEA/DEN, EDF R&D +// +// +// +// File : Partition_Loop3d.hxx +// Module : GEOM + +#ifndef _Partition_Loop3d_HeaderFile +#define _Partition_Loop3d_HeaderFile + +#ifndef _TopTools_ListOfShape_HeaderFile +#include +#endif +#ifndef _TopTools_IndexedDataMapOfShapeListOfShape_HeaderFile +#include +#endif +#ifndef _Standard_Boolean_HeaderFile +#include +#endif +#ifndef _Standard_Real_HeaderFile +#include +#endif +class TopoDS_Shape; +class TopTools_ListOfShape; +class TopTools_MapOfOrientedShape; +class TopoDS_Edge; +class TopoDS_Face; +class gp_Vec; + + +#ifndef _Standard_HeaderFile +#include +#endif +#ifndef _Standard_Macro_HeaderFile +#include +#endif + +class Partition_Loop3d { + +public: + + void* operator new(size_t,void* anAddress) + { + return anAddress; + } + void* operator new(size_t size) + { + return Standard::Allocate(size); + } + void operator delete(void *anAddress) + { + if (anAddress) Standard::Free((Standard_Address&)anAddress); + } + // Methods PUBLIC + // +Standard_EXPORT Partition_Loop3d(); +Standard_EXPORT void AddConstFaces(const TopoDS_Shape& S) ; +Standard_EXPORT void AddSectionFaces(const TopoDS_Shape& S) ; +Standard_EXPORT const TopTools_ListOfShape& MakeShells(const TopTools_MapOfOrientedShape& AvoidFacesMap) ; +Standard_EXPORT static Standard_Boolean IsInside(const TopoDS_Edge& E,const TopoDS_Face& F1,const TopoDS_Face& F2,const Standard_Boolean CountDot,Standard_Real& Dot,Standard_Boolean& GoodOri) ; +Standard_EXPORT static gp_Vec Normal(const TopoDS_Edge& E,const TopoDS_Face& F) ; + + + + + +protected: + + // Methods PROTECTED + // + + + // Fields PROTECTED + // + + +private: + + // Methods PRIVATE + // + + + // Fields PRIVATE + // +TopTools_ListOfShape myNewShells; +TopTools_ListOfShape myFaces; +TopTools_IndexedDataMapOfShapeListOfShape myEFMap; + + +}; + + + + + +// other Inline functions and methods (like "C++: function call" methods) +// + + +#endif diff --git a/PARTITION/Partition_Loop3d.ixx b/PARTITION/Partition_Loop3d.ixx new file mode 100644 index 000000000..a661b3242 --- /dev/null +++ b/PARTITION/Partition_Loop3d.ixx @@ -0,0 +1,14 @@ +// GEOM PARTITION : partition algorithm +// +// Copyright (C) 2003 CEA/DEN, EDF R&D +// +// +// +// File : Partition_Loop3d.ixx +// Module : GEOM + +#include "Partition_Loop3d.jxx" + + + + diff --git a/PARTITION/Partition_Loop3d.jxx b/PARTITION/Partition_Loop3d.jxx new file mode 100644 index 000000000..9b654f41b --- /dev/null +++ b/PARTITION/Partition_Loop3d.jxx @@ -0,0 +1,30 @@ +// GEOM PARTITION : partition algorithm +// +// Copyright (C) 2003 CEA/DEN, EDF R&D +// +// +// +// File : Partition_Loop3d.jxx +// Module : GEOM + +#ifndef _TopoDS_Shape_HeaderFile +#include +#endif +#ifndef _TopTools_ListOfShape_HeaderFile +#include +#endif +#ifndef _TopTools_MapOfOrientedShape_HeaderFile +#include +#endif +#ifndef _TopoDS_Edge_HeaderFile +#include +#endif +#ifndef _TopoDS_Face_HeaderFile +#include +#endif +#ifndef _gp_Vec_HeaderFile +#include +#endif +#ifndef _Partition_Loop3d_HeaderFile +#include "Partition_Loop3d.hxx" +#endif diff --git a/PARTITION/Partition_Spliter.cdl b/PARTITION/Partition_Spliter.cdl new file mode 100644 index 000000000..252e94b0b --- /dev/null +++ b/PARTITION/Partition_Spliter.cdl @@ -0,0 +1,165 @@ +-- 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 +-- +-- +-- +-- File : Partition_Spliter.cdl +-- Author : Benedicte MARTIN +-- Module : GEOM + +class Spliter from Partition + + ---Purpose: Split solids, shells and faces into parts of the + -- same topology if reconstruction level is not + -- limited. + +uses + Inter3d from Partition, + Loop2d from Partition, + Builder from BRep, + ShapeEnum from TopAbs, + Compound from TopoDS, + Face from TopoDS, + Edge from TopoDS, + Shape from TopoDS, + MapOfOrientedShape from TopTools, + IndexedMapOfShape from TopTools, + DataMapOfShapeShape from TopTools, + ListOfShape from TopTools, + MapOfShape from TopTools, + AsDes from BRepAlgo, + Image from BRepAlgo + +is + Create returns Spliter from Partition; + ---Purpose: constructor + + AddShape ( me : in out; S : Shape from TopoDS); + ---Purpose: add object Shape to be splitted. + -- If S is a COMPOUND or COMPSOLID, it will be + -- exploded in order to get more simple object + -- shapes. + -- Object shapes that are vertices, edges or wires + -- won't be splitted and won't be in a result. + + AddTool ( me : in out; S : Shape from TopoDS); + ---Purpose: add cutting tool + + Compute (me : in out; Limit : ShapeEnum from TopAbs + = TopAbs_SHAPE); + ---Purpose: produce a result which is a compound of parts of + -- object shapes. A part can be either a vertex, + -- edge, wire, face, shell or solid. + -- By default, a part is of the same topology as an + -- object shape, else restricts parts + -- reconstruction. + -- If == TopAbs_VERTEX, only new vertices are + -- returned in the result + + KeepShapesInside (me : in out; S : Shape from TopoDS); + ---Purpose: remove shapes that are outside of S from result. + -- S should be an object shape. + ---Warning: call it after Compute() + + RemoveShapesInside (me : in out; S : Shape from TopoDS); + ---Purpose: remove shapes that are inside S from result. + -- S should be an object shape. + ---Warning: call it after Compute() + + Shape ( me ) returns Shape from TopoDS; + ---Purpose: return resulting compound + + Clear ( me : in out); + ---Purpose: clear fields + + + ---Category: private methods + + + MakeShells (me: in out; S : Shape from TopoDS; + NS: in out ListOfShape from TopTools) is private; + ---Purpose: split S into shells + + MakeFaces (me: in out; S : Shape from TopoDS) + returns Shape from TopoDS is private; + ---Purpose: split faces of S, return compound of new faces + + MakeEdges (me; + E : Edge from TopoDS; + VOnE : ListOfShape from TopTools; + NE : in out ListOfShape from TopTools) + is private; + ---Purpose: cut E by vertices VOnE, return list of new edges + -- NE + + FindFacesInside (me: in out; S : Shape from TopoDS; + CheckClosed : Boolean = Standard_False; + All : Boolean = Standard_False) + returns Shape from TopoDS is private; + ---Purpose: return compound of faces of other shapes that are + -- inside . must have image in myImageShape. + -- makes avoid faces that do not form a + -- closed shell + -- makes return already added faces + + CheckTool ( me: in out; S : Shape from TopoDS) + returns Boolean from Standard is private; + ---Purpose: Return True if is a tool shape. Prepare tool + -- faces of for the search of internal faces. + + MergeEqualEdges (me: in out; LE : ListOfShape from TopTools) is private; + ---Purpose: among LE, find equal edges, choose ones to keep + -- and make them have pcurves on all faces they are + -- shared by + -- contains edge splits + +fields + + myDoneStep : ShapeEnum from TopAbs; -- reconstructed topology + 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 + myFaceShapeMap : DataMapOfShapeShape from TopTools; -- to find a shape by face + + myNewSection : MapOfShape from TopTools; -- new secton edges + + myAsDes : AsDes from BRepAlgo; + myImagesFaces : Image from BRepAlgo; + myImagesEdges : Image from BRepAlgo; + myImageShape : Image from BRepAlgo; + + -- contains info of same domain shapes and section edges + myInter3d : Inter3d from Partition; + + -- avoid rebuilding twice commont part of solids + myAddedFacesMap: MapOfOrientedShape from TopTools; + + -- equal splits + myEqualEdges : MapOfShape from TopTools; + + -- shape and its internal faces + myInternalFaces: DataMapOfShapeShape from TopTools; + myIntNotClFaces: DataMapOfShapeShape from TopTools;-- internal but not closed + +end Spliter; diff --git a/PARTITION/Partition_Spliter.cxx b/PARTITION/Partition_Spliter.cxx new file mode 100644 index 000000000..502fbc956 --- /dev/null +++ b/PARTITION/Partition_Spliter.cxx @@ -0,0 +1,1685 @@ +// 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 +// +// +// +// File : Partition_Spliter.cxx +// Author : Benedicte MARTIN +// Module : GEOM +// $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 "utilities.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#ifdef DEB +#define DRAW 0 +#endif + +#ifdef DRAW +#include +Standard_IMPORT Standard_Boolean AffichInter3d ; +Standard_IMPORT Standard_Boolean AffichInter2d ; +Standard_IMPORT Standard_Boolean AffichVertex; +Standard_IMPORT Standard_Boolean AffichFace; +Standard_IMPORT Standard_Boolean AffichWire; +Standard_IMPORT Standard_Boolean SelectFace; + +static char* names = new char[100]; + +#endif + +//======================================================================= +//function : Partition_Spliter +//purpose : constructor +//======================================================================= + +Partition_Spliter::Partition_Spliter() +{ + myAsDes = new BRepAlgo_AsDes; + Clear(); +} + +//======================================================================= +//function : AddTool +//purpose : add cutting tool that will _NOT_ be in result +//======================================================================= + +void Partition_Spliter::AddTool(const TopoDS_Shape& S) +{ + for (TopExp_Explorer exp(S,TopAbs_FACE); exp.More(); exp.Next()) + myMapTools.Add(exp.Current()); +} + +//======================================================================= +//function : AddShape +//purpose : add object Shape to be splited +//======================================================================= + +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()); + return; + } + + TopExp_Explorer exp(S,TopAbs_FACE); + if (!exp.More()) { // do not split edges and vertices + //myBuilder.Add( myShape, S ); + return; + } + + myListShapes.Append(S); + + for (; exp.More(); exp.Next()) { + myFaceShapeMap.Bind( exp.Current(), S ); + myMapFaces.Add(exp.Current()); + myImagesFaces.SetRoot(exp.Current()); + } +} + +//======================================================================= +//function : Shape +//purpose : return resulting compound +//======================================================================= + +TopoDS_Shape Partition_Spliter::Shape() const +{ + return myShape; +} + +//======================================================================= +//function : Clear +//purpose : clear fields +//======================================================================= + +void Partition_Spliter::Clear() +{ + myDoneStep = TopAbs_SHAPE; + + myListShapes.Clear(); + myMapFaces.Clear(); + myMapTools.Clear(); + myFaceShapeMap.Clear(); + + myNewSection.Clear(); + + myAsDes->Clear(); + myImagesFaces.Clear(); + myImagesEdges.Clear(); + myImageShape.Clear(); + + myInter3d = Partition_Inter3d(myAsDes); + + myAddedFacesMap.Clear(); + + myInternalFaces.Clear(); +} + +//======================================================================= +//function : Compute +//purpose : produce a result +//======================================================================= + +void Partition_Spliter::Compute(const TopAbs_ShapeEnum Limit) +{ + if ((Limit != TopAbs_SHAPE && myDoneStep == Limit) || + (Limit == TopAbs_SHAPE && myDoneStep == TopAbs_SOLID)) + return; + + myBuilder.MakeCompound( myShape ); + + TopTools_MapIteratorOfMapOfShape it; + TopTools_ListIteratorOfListOfShape itl; + TopExp_Explorer exp; + + if (myDoneStep > TopAbs_VERTEX) { + + TopTools_ListOfShape aListFaces; + aListFaces = myImagesFaces.Roots(); + for (it.Initialize(myMapTools); it.More(); it.Next()) + aListFaces.Append(it.Key()); + + //----------------------------------------------- + // 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()); + } + } +#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 existing vertices to edges of object faces in myAsDes + TopTools_MapOfShape DoneEM; + for ( it.Initialize(myMapFaces); it.More(); it.Next()) { + const TopoDS_Shape& F = it.Key(); + TopoDS_Face FForward = TopoDS::Face(F.Oriented(TopAbs_FORWARD)); + for (exp.Init(FForward,TopAbs_EDGE); exp.More(); exp.Next()) { + const TopoDS_Edge& E = TopoDS::Edge( exp.Current() ); + myAsDes->Add(FForward,E); + if (DoneEM.Add(E)) { + TopoDS_Iterator itV(E); + for (; itV.More(); itV.Next()) { + const TopoDS_Vertex& V = TopoDS::Vertex( itV.Value()); + myAsDes->Add(E, myInter3d.ReplaceSameDomainV( V, E )); + } + } + } + } + + // intersect edges that are descendants of a face in myAsDes + for ( it.Initialize(Modif); it.More(); it.Next()) { + const TopoDS_Face& F = TopoDS::Face(it.Key()); + Partition_Inter2d::CompletPart2d (myAsDes, F, NewEdges); + } + // now myAsDes contains also new vertices made at edge intersection as + // descendant of edges both new and old + + myDoneStep = TopAbs_VERTEX; + + } // if (myDoneStep > TopAbs_VERTEX) + + if (Limit == TopAbs_VERTEX) { + // add new vertices to myShape + for ( it.Initialize( myInter3d.NewEdges() ); it.More(); it.Next()) { + if (! myAsDes->HasDescendant( it.Key() )) + continue; + itl.Initialize( myAsDes->Descendant( it.Key() )); + for (; itl.More(); itl.Next()) + myBuilder.Add ( myShape, itl.Value() ); + } + return; + } + + if (myDoneStep > TopAbs_EDGE) { + + //----------------------------------------------- + // 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(); + TopTools_ListOfShape LSE; // all edge splits + for ( it.Initialize(NewEdges); it.More(); it.Next()) { + + TopoDS_Vertex V1,V2; + TopoDS_Edge EE = TopoDS::Edge(it.Key()); + + TopTools_ListOfShape aListV, aListF; + aListV = myAsDes->Descendant(EE); // intersection vertices + aListF = myAsDes->Ascendant(EE); // intersected faces + + 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()) ) ) + { + TopExp::Vertices(EE,V1,V2); + Standard_Real Tol = Max (BRep_Tool::Tolerance( V1 ), + BRep_Tool::Tolerance( V2 )); + + gp_Pnt P1 = BRep_Tool::Pnt(V1); + gp_Pnt P2 = BRep_Tool::Pnt(V2); + Standard_Boolean AddV1 = Standard_True; + Standard_Boolean AddV2 = Standard_True; + + // add only if there is no intersection at end vertex + for (itl.Initialize(aListV); itl.More(); itl.Next()) { + const TopoDS_Vertex& Ve = TopoDS::Vertex(itl.Value()) ; + Standard_Real Tol2 = Max ( Tol, BRep_Tool::Tolerance( Ve )); + Tol2 *= Tol2; + gp_Pnt P = BRep_Tool::Pnt(Ve); + if (AddV1 && P.SquareDistance(P1) <= Tol2) + AddV1 = Standard_False; + + if (AddV2 && P.SquareDistance(P2) <= Tol2) + AddV2 = Standard_False; + } + + if (AddV1) { + aListV.Append(V1); + myAsDes->Add(EE,V1); + } + + if (AddV2) { + aListV.Append(V2); + 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 + + 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); + LSE.Append( LNE ); + } + } + + // 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() ); + if ( myImagesEdges.HasImage( EE )) + continue; + TopTools_ListOfShape LNE; + const TopTools_ListOfShape& aListVV = myAsDes->Descendant(EE); + MakeEdges (EE, aListVV, LNE); + myImagesEdges.Bind(EE,LNE); + LSE.Append( LNE ); + } + } + + MergeEqualEdges( LSE ); + + myDoneStep = TopAbs_EDGE; + + } // if (myDoneStep > TopAbs_EDGE) + + if (Limit == TopAbs_EDGE) { + // add splits of old edges + TopTools_ListIteratorOfListOfShape itNE; + for (itl.Initialize( myListShapes );itl.More();itl.Next()) { + for ( exp.Init( itl.Value(), TopAbs_EDGE ); exp.More(); exp.Next()) { + itNE.Initialize( myImagesEdges.Image( exp.Current() )); + for ( ; itNE.More(); itNE.Next()) + myBuilder.Add ( myShape, itNE.Value() ); + } + } + // add splits of new edges + for ( it.Initialize( myInter3d.NewEdges() ); it.More(); it.Next()) { + itNE.Initialize( myImagesEdges.Image( it.Key() )); + for (; itNE.More(); itNE.Next()) + myBuilder.Add ( myShape, itNE.Value() ); + } + return; + } + + // make faces interfering by section edges share the same splits + //ProcessSectionEdges( SectionEdgesAD ); + + + //----------------------------------------------- + // split faces + //----------------------------------------------- + + if (myDoneStep > TopAbs_FACE) { + + for (itl.Initialize(myListShapes);itl.More();itl.Next()) { + TopoDS_Shape FacesComp = MakeFaces ( itl.Value()); + // there is a cunning here: myImagesFaces keeps faces made by Loop2d + // but some of them may be replaced with splits of same domain face + // and myImageShape keeps ultimate result + myImageShape.Bind( itl.Value(), FacesComp ); + } + + myDoneStep = TopAbs_FACE; + } + + if (Limit == TopAbs_WIRE || + Limit == TopAbs_FACE) { + for (itl.Initialize(myListShapes);itl.More();itl.Next()) { + if ( myMapTools.Contains( itl.Value() )) + continue; // no result needed for a tool face + const TopoDS_Shape& FacesComp = myImageShape.Image( itl.Value() ).First(); + for ( exp.Init( FacesComp, Limit); exp.More(); exp.Next()) + myBuilder.Add ( myShape, exp.Current()); + } + return; + } + + + //----------------------------------------------- + // split solids + //----------------------------------------------- + + // 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()) { + 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()); + } + } + + //----------------------------------------------- + // split shells + //----------------------------------------------- + + 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(); + if (S.ShapeType() != TopAbs_FACE || + 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()); + } + + 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 +//======================================================================= + +void Partition_Spliter::MakeEdges (const TopoDS_Edge& E, + const TopTools_ListOfShape& VOnE, + TopTools_ListOfShape& NE ) const +{ + TopoDS_Edge WE = E; + WE.Orientation(TopAbs_FORWARD); + + TopTools_ListIteratorOfListOfShape itv(VOnE); + TopTools_SequenceOfShape SV; + + 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; + } + } + + for (; itv.More(); itv.Next()) + SV.Append(itv.Value()); + + Tri( WE, SV); + + 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 : FindFacesInside +//purpose : return compound of faces of other shapes that are +// inside . +// is an object shape. +// makes avoid faces that do not form a +// closed shell +// makes return already added faces +//======================================================================= + +TopoDS_Shape Partition_Spliter::FindFacesInside(const TopoDS_Shape& theShape, + const Standard_Boolean CheckClosed, + const Standard_Boolean All) +{ + TopExp_Explorer expl; + if (myInternalFaces.IsBound( theShape )) + { + TopoDS_Shape aIntFComp = myInternalFaces.Find ( theShape ); + TopoDS_Shape aIntRemFComp = myIntNotClFaces.Find ( theShape ); + + expl.Init( aIntRemFComp, TopAbs_FACE); + if (CheckClosed || !expl.More()) + return aIntFComp; + + TopoDS_Compound C; + myBuilder.MakeCompound( C ); + // add removed faces + for (; expl.More(); expl.Next()) + myBuilder.Add( C, expl.Current() ); + // add good internal faces + for (expl.Init( aIntFComp, TopAbs_FACE); expl.More(); expl.Next()) + myBuilder.Add( C, expl.Current() ); + return C; + } + + // compound of split faces of theShape + const TopoDS_Shape& CSF = myImageShape.Image(theShape).First(); + + TopTools_MapOfShape MSE, MFP; + TopTools_DataMapOfShapeListOfShape DMSEFP; + TopTools_MapIteratorOfMapOfShape itm; + TopTools_ListOfShape EmptyL; + + // MSE filling: map of new section edges of CSF + for (expl.Init(CSF,TopAbs_EDGE); expl.More(); expl.Next()) { + TopoDS_Shape resE = expl.Current() ; + if (myNewSection.Contains( resE )) // only new edges + MSE.Add(resE); + } + + // DMEF: map edge of CSF - faces of CSF + TopTools_IndexedDataMapOfShapeListOfShape DMEF; + TopExp::MapShapesAndAncestors(CSF, TopAbs_EDGE, TopAbs_FACE, DMEF); + + // Fill + // 1. MFP - a map of faces to process: map of resulting faces except + // those of theShape; we`ll add to C those of them which are inside CSF + // 2. DMSEFP - edge of MSE => faces of MFP + TopTools_ListIteratorOfListOfShape itl; + for (itl.Initialize(myListShapes);itl.More();itl.Next()) { + const TopoDS_Shape& aShape = itl.Value(); + if ( theShape.IsSame( aShape )) continue; + // fill maps + // iterate on split faces of aShape + TopoDS_Iterator itF ( myImageShape.Image(aShape).First() ); + for ( ; itF.More(); itF.Next()) { + const TopoDS_Shape& sf = itF.Value(); + MFP.Add(sf); + // iterate on edges of split faces of aShape, + // add to DMSEFP edges that are new + for (expl.Init( sf, 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(sf); + } + } + } + } + + // find faces inside theShape + + Standard_Boolean skipAlreadyAdded = Standard_False; + Standard_Boolean GoodOri, inside; + Standard_Real dot; + TopTools_ListOfShape KeepFaces; + TopTools_DataMapIteratorOfDataMapOfShapeListOfShape Mapit; + + // iterate on section edges, check faces of other shapes + // sharing section edges and put internal faces to KeepFaces + for (Mapit.Initialize(DMSEFP); Mapit.More() ; Mapit.Next() ) { + // a new edge of 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 + Standard_Boolean isSectionE = myInter3d.IsSectionEdge ( OrigE ); + + // split faces of other shapes sharing E + TopTools_ListOfShape& LSF = DMSEFP.ChangeFind(E); + itl.Initialize( LSF ); + while (itl.More()) { + // a split faces of other shape + TopoDS_Face aFace1 = TopoDS::Face(itl.Value()); + // remove aFace1 form DMSEFP and MFP + LSF.Remove( itl ); // == itl.Next(); + if (!MFP.Remove( aFace1 )) + continue; // was not is MFP ( i.e already checked) + // check if aFace1 was already added to 2 shells + if (!All && + myAddedFacesMap.Contains( aFace1 ) && + myAddedFacesMap.Contains( aFace1.Reversed() )) { + skipAlreadyAdded = Standard_True; + continue; + } + + // 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 aFace2; + if ( !isSectionE ) { + while (itl.More()) { + aFace2 = itl.Value(); + if (!MFP.Contains( aFace2 )) { + LSF.Remove( itl ); + continue; + } + if (anOrigFace.IsSame( myImagesFaces.Root( aFace2 ))) + break; + itl.Next(); + } + if (itl.More()) { // aFace2 found, remove it from maps + LSF.Remove( itl ); + MFP.Remove(aFace2); + } + else + aFace2.Nullify(); + itl.Initialize( LSF ); + } + + // check that anOrigFace is not same domain with CSF faces it intersects + + const TopTools_ListOfShape& FL = DMEF.FindFromKey(E); //faces of CSF sharing E + const TopoDS_Shape& origF1 = myImagesFaces.Root(FL.First()); + const TopoDS_Shape& origF2 = myImagesFaces.Root(FL.Last()); + Standard_Boolean sameDom1 = anOrigFace.IsSame( origF1 ); + Standard_Boolean sameDom2 = anOrigFace.IsSame( origF2 ); + if (!(sameDom1 || sameDom2) && myInter3d.HasSameDomainF( anOrigFace )) { + sameDom1 = myInter3d.IsSameDomainF( anOrigFace, origF1); + if (origF1 == origF2) + sameDom2 = sameDom1; + else + myInter3d.IsSameDomainF( anOrigFace, origF2); + } + if (sameDom1 && sameDom2) + continue; + if ((sameDom1 || sameDom2)) { + inside = Partition_Loop3d::IsInside (E, + TopoDS::Face(FL.First()), + TopoDS::Face(FL.Last()), + 1, dot, GoodOri); + if (inside || (dot + Precision::Angular() >= 1.0)) + continue; // E is convex between origF1 and origF2 or they are tangent + } + + + // keep one of found faces + + //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); + // store internal face + if (inside) + KeepFaces.Append(aFace1); + else if (!aFace2.IsNull()) + { + if (dot + Precision::Angular() >= 1.0) + { + // aFace2 state is not clear, it will be analysed alone, + // put it back to the maps + MFP.Add( aFace2 ); + LSF.Append( aFace2 ); + } + else + KeepFaces.Append(aFace2); + } + } + } + + // add not distributed faces connected with KeepFaces + + // ultimate list of internal faces + TopTools_ListOfShape KeptFaces; + + // add to MFP not split tool faces as well, they may be connected with + // tool faces interfering with theShape + for ( itm.Initialize(myMapTools); itm.More(); itm.Next() ) { + const TopoDS_Shape& aToolFace = itm.Key(); + if (!myImageShape.HasImage(aToolFace)) + MFP.Add (aToolFace); + } + + if (MFP.IsEmpty()) + KeptFaces.Append (KeepFaces); + + while (!KeepFaces.IsEmpty()) + { + // KeepEdges : map of edges of faces kept last time + TopTools_IndexedMapOfShape KeepEdges; + for ( itl.Initialize(KeepFaces); itl.More(); itl.Next() ) { + TopExp::MapShapes( itl.Value(), TopAbs_EDGE, KeepEdges); + KeptFaces.Append( itl.Value() ); + } + + KeepFaces.Clear(); + + // keep faces connected with already kept faces by KeepEdges + for ( itm.Initialize(MFP); itm.More(); itm.Next() ) { + const TopoDS_Shape& FP = itm.Key(); + for (expl.Init(FP,TopAbs_EDGE); expl.More(); expl.Next()) { + const TopoDS_Shape& se = expl.Current(); + if (!MSE.Contains(se) && KeepEdges.Contains(se) ) { + KeepFaces.Append(FP); + MFP.Remove(FP); + break; + } + } + } + } + + // check if kept faces form a shell without free edges + + 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_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 )) + isClosed = ( DMEF(i).Extent() != 1 ); + } + if (!isClosed) { + const TopoDS_Shape& F = DMEF.FindFromIndex( i-1 ).First(); // bad face + MFP.Add( F ); + // remove bad face from DMEF + for (expl.Init( F, TopAbs_EDGE); expl.More(); expl.Next()) { + const TopoDS_Shape& E = expl.Current(); + TopTools_ListOfShape& FL = DMEF.ChangeFromKey( E ); + for (itl.Initialize( FL ); itl.More(); itl.Next() ) { + if ( F.IsSame( itl.Value() )) { + FL.Remove( itl ); + break; + } + } + } + } + } + } + + // a result compound + TopoDS_Compound C; + // compound of removed internal faces + TopoDS_Compound CNotCl; + + myBuilder.MakeCompound(C); + myBuilder.MakeCompound(CNotCl); + + // add to compounds + for (itl.Initialize(KeptFaces); itl.More(); itl.Next() ) + { + TopoDS_Shape & aIntFace = itl.Value(); + if (! MFP.Contains( aIntFace )) + myBuilder.Add( C, aIntFace); + else + myBuilder.Add( CNotCl, aIntFace); + } + + if (!skipAlreadyAdded && CheckClosed) + { + myInternalFaces.Bind( theShape, C ); + myIntNotClFaces.Bind( theShape, CNotCl ); + } + + return C; +} + +//======================================================================= +//function : MakeShell +//purpose : split S into compound of shells +//======================================================================= + +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) { + 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: + // 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()) { + + 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 +// ==True makes consider same edges as equal +// Put in all equal edges +//======================================================================= + +static void findEqual (const TopTools_ListOfShape& EL1, + const TopTools_ListOfShape& EL2, + const Standard_Boolean addSame, + TopTools_DataMapOfShapeListOfShape& EEM, + TopTools_MapOfShape& AllEqMap) +{ + // map vertices to edges for EL2 + TopTools_DataMapOfShapeListOfShape VEM; + TopTools_ListIteratorOfListOfShape itE1, itE2(EL2); + TopoDS_Iterator itV; + TopTools_ListOfShape emptyL; + for (; itE2.More(); itE2.Next()) { + for (itV.Initialize( itE2.Value() ); itV.More(); itV.Next()) { + const TopoDS_Shape& V = itV.Value(); + if (! VEM.IsBound( V ) ) + VEM.Bind( V, emptyL); + VEM( V ).Append( itE2.Value()); + } + } + + gp_Vec D1, D2; + gp_Pnt P; + Standard_Real f,l,u,tol; + Handle(Geom_Curve) C1, C2; + Extrema_ExtPC Extrema; + TopoDS_Vertex V1, V2, V3, V4; + + AllEqMap.Clear(); + + for (itE1.Initialize(EL1); itE1.More(); itE1.Next()) { + const TopoDS_Edge& E1 = TopoDS::Edge( itE1.Value()); + if (BRep_Tool::Degenerated( E1 ) || AllEqMap.Contains (E1)) + continue; + TopExp::Vertices( E1, V1, V2 ); + + if (VEM.IsBound(V1)) + itE2.Initialize( VEM(V1) ); + for (; itE2.More(); itE2.Next()) { + const TopoDS_Edge& E2 = TopoDS::Edge( itE2.Value()); + if (BRep_Tool::Degenerated( E2 )) + continue; + + if (E1.IsSame(E2)) { + if (!addSame) + continue; + } + else { + TopExp::Vertices( E2, V3, V4); + if (!V2.IsSame(V4) && !V2.IsSame(V3)) + continue; + // E1 and E2 have same vertices + // check D1 at end points. + C2 = BRep_Tool::Curve( E2, f,l); + C1 = BRep_Tool::Curve( E1, f,l); + u = BRep_Tool::Parameter(V1,E1); + C1->D1(u, P, D1); + u = BRep_Tool::Parameter(V1.IsSame(V3) ? V3 : V4, E2); + C2->D1(u, P, D2); + D1.Normalize(); D2.Normalize(); + if (Abs(D1*D2) + Precision::Angular() < 1.0) + continue; + if (! V1.IsSame(V2)) { + u = BRep_Tool::Parameter(V2,E1); + C1->D1(u, P, D1); + u = BRep_Tool::Parameter(V2.IsSame(V3) ? V3 : V4, E2); + C2->D1(u, P, D2); + D1.Normalize(); D2.Normalize(); + if (Abs(D1*D2) + Precision::Angular() < 1.0) + continue; + } + // check distance at a couple of internal points + tol = Max(BRep_Tool::Tolerance(E1), + BRep_Tool::Tolerance(E2)); + GeomAdaptor_Curve AC1(C1); + Extrema.Initialize(AC1,f,l); + Standard_Boolean ok = Standard_True, hasMin = Standard_False; + BRep_Tool::Range( E2, f, l); + Standard_Integer i=1, nbi=3; + for (; iValue( f+(l-f)*i/nbi )); + Standard_Integer j=1, nbj=Extrema.NbExt(); + for (; j<=nbj && ok; ++j) { + if (Extrema.IsMin(j)) { + hasMin = Standard_True; + ok = Extrema.Value(j) <= tol; + } + } + } + if ( !hasMin || !ok) + continue; + } + // bind E2 to E1 in EEM + if (!EEM.IsBound(E1)) { + EEM.Bind (E1, emptyL); + AllEqMap.Add (E1); + } + EEM(E1).Append(E2); + AllEqMap.Add (E2); + } + } +} + +//======================================================================= +//function : MakeFaces +//purpose : split faces of S, return compound of new faces +//======================================================================= + +TopoDS_Shape Partition_Spliter::MakeFaces (const TopoDS_Shape& S) +{ + TopoDS_Compound C; + myBuilder.MakeCompound(C); + + TopTools_ListIteratorOfListOfShape itl, itNE; + + TopExp_Explorer exp(S,TopAbs_FACE); + for (; exp.More(); exp.Next()) { + + const TopoDS_Face& F = TopoDS::Face(exp.Current()); + + TopTools_ListOfShape LNF; + + if (myImagesFaces.HasImage( F )) { + myImagesFaces.LastImage( F, LNF ); + TopAbs_Orientation oriF = F.Orientation(); + for ( itl.Initialize( LNF ); itl.More(); itl.Next()) + itl.Value().Orientation( oriF ); + } + else { + + Partition_Loop2d loops; + loops.Init(F); + + TopTools_IndexedMapOfShape EM; + TopExp::MapShapes( F, TopAbs_EDGE, EM); + + TopTools_MapOfShape AddedEqualM; + Standard_Boolean needRebuild = Standard_False; + + // add splits to loops + + // LE: old edges + new not splitted edges + const TopTools_ListOfShape& LE = myAsDes->Descendant(F); + for (itl.Initialize(LE); itl.More(); itl.Next()) { + const TopoDS_Edge& E = TopoDS::Edge( itl.Value() ); + + Standard_Boolean isSectionE = myInter3d.IsSectionEdge(E); + Standard_Boolean isNewE = !EM.Contains( E ); + + // LSE: list of split edges + TopTools_ListOfShape LSE; + myImagesEdges.LastImage(E,LSE); // splits of E or E itself + + for (itNE.Initialize(LSE); itNE.More(); itNE.Next()) { + + TopoDS_Edge NE = TopoDS::Edge( itNE.Value() ); + Standard_Boolean isSameE = NE.IsSame ( E ); + + if ( isNewE || isSectionE || !isSameE) { + if (AddedEqualM.Contains( NE )) + continue; + + if (isNewE) { + if (isSectionE) { + if ( ! myInter3d.IsSplitOn( NE, E, F) ) + continue; + } + else { + TopoDS_Vertex V1,V2; + TopExp::Vertices(NE,V1,V2); + const TopTools_ListOfShape& EL1 = myAsDes->Ascendant(V1); + const TopTools_ListOfShape& EL2 = myAsDes->Ascendant(V2); + if ( EL1.Extent() < 2 && EL2.Extent() < 2 ) + continue; + } + } + else { + NE.Orientation( E.Orientation()); + if (!isSameE) { + // orient NE because it may be a split of other edge + Standard_Real f,l,u; + Handle(Geom_Curve) C3d = BRep_Tool::Curve( E,f,l ); + Handle(Geom_Curve) NC3d = BRep_Tool::Curve( NE,f,l); + if ( C3d != NC3d) { + gp_Vec D1, ND1; gp_Pnt P; + TopoDS_Vertex V = TopExp::FirstVertex(NE); + u = BRep_Tool::Parameter(V,NE); + NC3d->D1 (u, P, ND1); + u = BRep_Tool::Parameter(V,E); + C3d ->D1 (u, P, D1); + if (ND1.Dot(D1) < 0) + NE.Reverse(); + } + } + } + if (myEqualEdges.Contains( NE ) && !AddedEqualM.Add( NE )) + continue; + + needRebuild = Standard_True; + } + + if (isNewE || isSectionE) + myNewSection.Add( NE ); + + if (isNewE) + loops.AddSectionEdge(NE); + else + loops.AddConstEdge(NE); + } + } + + //------------------- + // Build the faces. + //------------------- + + if (needRebuild) { + + loops.Perform(); + loops.WiresToFaces(myImagesEdges); + + LNF = loops.NewFaces(); + + myImagesFaces.Bind(F,LNF); + + // replace the result faces that have already been built + // during same domain faces reconstruction + if (myInter3d.HasSameDomainF( F )) { + // build map edge to same domain faces + TopTools_IndexedDataMapOfShapeListOfShape EFM; + TopTools_MapOfShape SDFM; // avoid doubling + itl.Initialize( myInter3d.SameDomain( F )); + for (; itl.More(); itl.Next()) { + if ( !myImagesFaces.HasImage( itl.Value() )) + continue; + TopTools_ListIteratorOfListOfShape itNF; + itNF.Initialize (myImagesFaces.Image( itl.Value() )); + for ( ; itNF.More(); itNF.Next()) { + TopoDS_Shape SDF = itNF.Value(); + if (myImagesFaces.HasImage( SDF )) // already replaced + SDF = myImagesFaces.Image( SDF ).First(); + if (SDFM.Add (SDF)) + TopExp::MapShapesAndAncestors(SDF, TopAbs_EDGE, TopAbs_FACE, EFM); + } + } + // do replace + TopTools_ListOfShape LOF; + if ( !EFM.IsEmpty() ) + itl.Initialize( LNF ); + while (itl.More()) { + const TopoDS_Shape& NF = itl.Value(); + TopExp_Explorer expE ( NF, TopAbs_EDGE ); + const TopoDS_Edge& E = TopoDS::Edge (expE.Current()); + if (EFM.Contains( E )) { + const TopTools_ListOfShape& SDFL = EFM.FindFromKey( E ); + TopoDS_Shape SDF = SDFL.First(); + Standard_Boolean GoodOri; + Standard_Real dot; + Partition_Loop3d::IsInside (E, TopoDS::Face(NF), TopoDS::Face(SDF), + 1, dot, GoodOri); + if (dot < 0) { + if (SDFL.Extent() == 1) { + itl.Next(); + continue; + } + else + SDF = SDFL.Last(); + } + gp_Vec V1 = Partition_Loop3d::Normal( E, TopoDS::Face( NF )); + gp_Vec V2 = Partition_Loop3d::Normal( E, TopoDS::Face( SDF )); + if (V1*V2 < 0) + SDF.Reverse(); + + if (!myImagesFaces.HasImage( NF )) + myImagesFaces.Bind( NF, SDF ); + + LOF.Prepend ( SDF ); + LNF.Remove (itl); + } + else + itl.Next(); + } + + LNF.Append (LOF); + } + } // if (needRebuild) + + else { + LNF.Append( F ); + myImagesFaces.Bind(F,LNF); + } + } // if (myImagesFaces.HasImage( F )) + + for (itl.Initialize(LNF); itl.More(); itl.Next()) + myBuilder.Add ( C, itl.Value()); + } // loop on faces of S + + return C; +} + +//======================================================================= +//function : MergeEqualEdges +//purpose : find equal edges, choose ones to keep and make +// them have pcurves on all faces they are shared by +//======================================================================= + +void Partition_Spliter::MergeEqualEdges (const TopTools_ListOfShape& LSE) +{ + // find equal edges + // map: edge - equal edges + TopTools_DataMapOfShapeListOfShape EEM( LSE.Extent() ); + findEqual (LSE, LSE, 0, EEM, myEqualEdges); + + TopTools_ListOfShape EEL; // list of equal edges + TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itM (EEM); + 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); + for (; itEE.More(); itEE.Next()) { + EKeep = TopoDS::Edge( itEE.Value() ); + const TopoDS_Edge& EKeepOrig = TopoDS::Edge( myImagesEdges.Root( EKeep )); + if (myInter3d.IsSectionEdge( EKeepOrig )) + break; + } + + 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; + 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 ); + + TopTools_ListIteratorOfListOfShape itF (FL); + for ( ; itF.More(); itF.Next()) { + 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); + C3d = new Geom_TrimmedCurve( C3d, f,l); + pc = TopOpeBRepTool_CurveTool::MakePCurveOnFace (F,C3d,tol); + if (pc.IsNull()) { + MESSAGE (" CANT BUILD PCURVE "); + } + myBuilder.UpdateEdge( EKeep, pc, F, tol); + } + } + // replace edges in faces + if (!myImagesEdges.HasImage( E )) + myImagesEdges.Bind( E, EKeep ); + } + } +} + +//======================================================================= +//function : KeepShapesInside +//purpose : remove shapes that are outside of S from resul +//======================================================================= + +void Partition_Spliter::KeepShapesInside (const TopoDS_Shape& S) +{ + TopoDS_Iterator it; + if (S.ShapeType() < TopAbs_SOLID) { // compound or compsolid + for (it.Initialize( S ); it.More(); it.Next()) + KeepShapesInside( it.Value()); + return; + } + + Standard_Boolean isTool = Standard_False; + if (!myImageShape.HasImage( S )) { + isTool = CheckTool( S ); + if (!isTool) return; + } + + // 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_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()) { + + TopExp_Explorer expResF( it.Value(), TopAbs_FACE ); + for (; expResF.More(); expResF.Next()) { + if ( MIF.Contains( expResF.Current())) { + myBuilder.Add( C, it.Value() ); + break; + } + } + } + + myShape = C; +} + +//======================================================================= +//function : RemoveShapesInside +//purpose : remove shapes that are inside S from resul +//======================================================================= + +void Partition_Spliter::RemoveShapesInside (const TopoDS_Shape& S) +{ + TopoDS_Iterator it; + if (S.ShapeType() < TopAbs_SOLID) { // compound or compsolid + for (it.Initialize( S ); it.More(); it.Next()) + RemoveShapesInside( it.Value()); + return; + } + Standard_Boolean isTool = Standard_False; + if (!myImageShape.HasImage( S )) { + isTool = CheckTool( S ); + if (!isTool) return; + } + + TopoDS_Shape InsFacesComp = FindFacesInside( S, Standard_False, Standard_True); + TopTools_IndexedMapOfShape MIF; // map of internal faces + TopExp::MapShapes( InsFacesComp, TopAbs_FACE, MIF); + + if (MIF.IsEmpty()) return; + + // add to MIF split faces of S + if (myImageShape.HasImage(S)) + TopExp::MapShapes( myImageShape.Image(S).First(), TopAbs_FACE, MIF); + + // leave in the result only those shapes not having all face in MIF + + TopoDS_Compound C; + myBuilder.MakeCompound(C); + + // RMF : faces of removed shapes that encounter once + TopTools_MapOfShape RFM; + + for (it.Initialize( myShape ); it.More(); it.Next()) { + + TopExp_Explorer expResF( it.Value(), TopAbs_FACE ); + for (; expResF.More(); expResF.Next()) + if (!MIF.Contains( expResF.Current())) + break; + + if (expResF.More()) + // add shape to result + myBuilder.Add( C, it.Value() ); + else + // add faces of a removed shape to RFM + for (expResF.ReInit(); expResF.More(); expResF.Next()) { + const TopoDS_Shape& F = expResF.Current(); + if ( ! RFM.Remove ( F )) + RFM.Add( F ); + } + } + + if (!isTool) { + + // rebuild S, it must remain in the result + + Standard_Boolean isClosed = Standard_False; + switch (S.ShapeType()) { + case TopAbs_SOLID : + isClosed = Standard_True; break; + case TopAbs_SHELL: { + TopTools_IndexedDataMapOfShapeListOfShape MEF; + TopExp::MapShapesAndAncestors(S, TopAbs_EDGE, TopAbs_FACE, MEF); + Standard_Integer i; + for (i=1; isClosed && i<=MEF.Extent(); ++i) + isClosed = ( MEF(i).Extent() != 1 ); + break; + } + default: + isClosed = Standard_False; + } + if (isClosed) { + + // add to a new shape external faces of removed shapes, ie those in RFM + + TopoDS_Shell Shell; + myBuilder.MakeShell( Shell ); + + // exclude redundant internal face with edges encounterd only once + TopTools_IndexedDataMapOfShapeListOfShape MEF; + TopTools_MapIteratorOfMapOfShape itF (RFM); + for ( ; itF.More(); itF.Next()) + TopExp::MapShapesAndAncestors(itF.Key(), TopAbs_EDGE, TopAbs_FACE, MEF); + + // add only faces forming a closed shell + for (itF.Reset() ; itF.More(); itF.Next()) + { + TopExp_Explorer expE (itF.Key(), TopAbs_EDGE); + for (; expE.More(); expE.Next()) + if (MEF.FindFromKey(expE.Current()).Extent() == 1) + break; + if (!expE.More()) + myBuilder.Add( Shell, itF.Key()); + } + + if (S.ShapeType() == TopAbs_SOLID) { + TopoDS_Solid Solid; + myBuilder.MakeSolid( Solid ); + myBuilder.Add (Solid, Shell); + myBuilder.Add (C, Solid); + } + else + myBuilder.Add (C, Shell); + } + else { + if (myImageShape.HasImage( S )) { + for (it.Initialize( myImageShape.Image(S).First()); it.More(); it.Next()) + myBuilder.Add (C, it.Value()); + } + } + } + + myShape = C; +} + +//======================================================================= +//function : CheckTool +//purpose : Return True if is a tool shape. Prepare tool +// faces of for the search of internal faces. +//======================================================================= + +Standard_Boolean Partition_Spliter::CheckTool(const TopoDS_Shape& S) +{ + // suppose S has not an image + + Standard_Boolean isTool = Standard_False; + TopoDS_Compound C; + myBuilder.MakeCompound( C ); + + TopExp_Explorer expF( S, TopAbs_FACE); + for (; expF.More(); expF.Next()) { + + const TopoDS_Face& F = TopoDS::Face( expF.Current() ); + if (myMapTools.Contains( F )) + isTool = Standard_True; + else + continue; + + if (myImagesFaces.HasImage( F )) { + // F has been reconstructed + TopAbs_Orientation Fori = F.Orientation(); + TopTools_ListOfShape LNF; + myImagesFaces.LastImage( F, LNF); + TopTools_ListIteratorOfListOfShape itF (LNF); + for ( ; itF.More(); itF.Next()) + myBuilder.Add( C, itF.Value().Oriented(Fori) ); + continue; + } + + Standard_Boolean hasSectionE = myInter3d.HasSectionEdge( F ); + Standard_Boolean hasNewE = myAsDes->HasDescendant( F ); + if (!hasSectionE && !hasNewE) + continue; // F intersects nothing + + // make an image for F + + TopoDS_Face NF = F; + NF.Orientation(TopAbs_FORWARD); + NF = TopoDS::Face( NF.EmptyCopied() ); // make a copy + TopoDS_Wire NW; + myBuilder.MakeWire( NW ); + + // add edges, as less as possible + TopTools_ListOfShape NEL; + TopTools_ListIteratorOfListOfShape itNE; + if (hasSectionE) { + // add section edges + TopExp_Explorer expE; + for ( ; expE.More(); expE.Next()) { + if (! myImagesEdges.HasImage( expE.Current() )) + continue; + myImagesEdges.LastImage( expE.Current(), NEL ); + for ( itNE.Initialize( NEL ); itNE.More(); itNE.Next()) + myBuilder.Add ( NW, itNE.Value()); + } + } + if (hasNewE) { + // add new adges + NEL = myAsDes->Descendant( F ); + for ( itNE.Initialize( NEL ); itNE.More(); itNE.Next()) { + TopTools_ListOfShape SEL; // splits + myImagesEdges.LastImage( itNE.Value(), SEL ); + TopTools_ListIteratorOfListOfShape itSE (SEL); + for ( ; itSE.More(); itSE.Next()) + myBuilder.Add ( NW, itSE.Value()); + } + } + myBuilder.Add( NF, NW ); + myBuilder.Add (C, NF); + + NF.Orientation( F.Orientation() ); // NF is most probably invalid + myImagesFaces.Bind (F, NF); + } + if (isTool) + myImageShape.Bind (S, C); + + return isTool; +} diff --git a/PARTITION/Partition_Spliter.hxx b/PARTITION/Partition_Spliter.hxx new file mode 100644 index 000000000..bb26915c1 --- /dev/null +++ b/PARTITION/Partition_Spliter.hxx @@ -0,0 +1,161 @@ +// 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 +// +// +// +// File : Partition_Spliter.hxx +// Module : GEOM + + +#ifndef _Partition_Spliter_HeaderFile +#define _Partition_Spliter_HeaderFile + +#ifndef _TopAbs_ShapeEnum_HeaderFile +#include +#endif +#ifndef _TopoDS_Compound_HeaderFile +#include +#endif +#ifndef _BRep_Builder_HeaderFile +#include +#endif +#ifndef _TopTools_ListOfShape_HeaderFile +#include +#endif +#ifndef _TopTools_MapOfShape_HeaderFile +#include +#endif +#ifndef _TopTools_DataMapOfShapeShape_HeaderFile +#include +#endif +#ifndef _Handle_BRepAlgo_AsDes_HeaderFile +#include +#endif +#ifndef _BRepAlgo_Image_HeaderFile +#include +#endif +#ifndef _Partition_Inter3d_HeaderFile +#include "Partition_Inter3d.hxx" +#endif +#ifndef _TopTools_MapOfOrientedShape_HeaderFile +#include +#endif +#ifndef _Standard_Boolean_HeaderFile +#include +#endif +class BRepAlgo_AsDes; +class TopoDS_Shape; +class TopTools_ListOfShape; +class TopoDS_Edge; + + +#ifndef _Standard_HeaderFile +#include +#endif +#ifndef _Standard_Macro_HeaderFile +#include +#endif + +class Partition_Spliter { + +public: + + void* operator new(size_t,void* anAddress) + { + return anAddress; + } + void* operator new(size_t size) + { + return Standard::Allocate(size); + } + void operator delete(void *anAddress) + { + if (anAddress) Standard::Free((Standard_Address&)anAddress); + } + // Methods PUBLIC + // +Standard_EXPORT Partition_Spliter(); +Standard_EXPORT void AddShape(const TopoDS_Shape& S) ; +Standard_EXPORT void AddTool(const TopoDS_Shape& S) ; +Standard_EXPORT void Compute(const TopAbs_ShapeEnum Limit = TopAbs_SHAPE) ; +Standard_EXPORT void KeepShapesInside(const TopoDS_Shape& S) ; +Standard_EXPORT void RemoveShapesInside(const TopoDS_Shape& S) ; +Standard_EXPORT TopoDS_Shape Shape() const; +Standard_EXPORT void Clear() ; + + + + + +protected: + + // Methods PROTECTED + // + + + // Fields PROTECTED + // + + +private: + + // Methods PRIVATE + // +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) ; + + + // Fields PRIVATE + // +TopAbs_ShapeEnum myDoneStep; +TopoDS_Compound myShape; +BRep_Builder myBuilder; +TopTools_ListOfShape myListShapes; +TopTools_MapOfShape myMapFaces; +TopTools_MapOfShape myMapTools; +TopTools_DataMapOfShapeShape myFaceShapeMap; +TopTools_MapOfShape myNewSection; +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; + + +}; + + + + + +// other Inline functions and methods (like "C++: function call" methods) +// + + +#endif diff --git a/PARTITION/Partition_Spliter.ixx b/PARTITION/Partition_Spliter.ixx new file mode 100644 index 000000000..ee8259468 --- /dev/null +++ b/PARTITION/Partition_Spliter.ixx @@ -0,0 +1,31 @@ +// 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 +// +// +// +// File : Partition_Spliter.ixx +// Module : GEOM + +#include "Partition_Spliter.jxx" + + + + diff --git a/PARTITION/Partition_Spliter.jxx b/PARTITION/Partition_Spliter.jxx new file mode 100644 index 000000000..bf8622c93 --- /dev/null +++ b/PARTITION/Partition_Spliter.jxx @@ -0,0 +1,41 @@ +// 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 +// +// +// +// File : Partition_Spliter.jxx +// Module : GEOM + +#ifndef _BRepAlgo_AsDes_HeaderFile +#include +#endif +#ifndef _TopoDS_Shape_HeaderFile +#include +#endif +#ifndef _TopTools_ListOfShape_HeaderFile +#include +#endif +#ifndef _TopoDS_Edge_HeaderFile +#include +#endif +#ifndef _Partition_Spliter_HeaderFile +#include "Partition_Spliter.hxx" +#endif diff --git a/SKETCHER/GEOM_Sketcher.cxx b/SKETCHER/GEOM_Sketcher.cxx new file mode 100644 index 000000000..7734c2b8f --- /dev/null +++ b/SKETCHER/GEOM_Sketcher.cxx @@ -0,0 +1,1389 @@ +// GEOM SKETCHER : basic sketcher +// +// 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 +// +// +// +// File : GEOM_Sketcher.cxx +// Author : Nicolas REJNERI +// Module : GEOM +// $Header$ + +using namespace std; +#include "GEOM_Sketcher.h" +#include "utilities.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +/*! + \class GEOM_Sketcher GEOM_Sketcher.h + \brief ... +*/ + +Standard_Real resol = 1.0; + +/*! + Constructor. +*/ +Sketch::Sketch() +{ + +} + +/*! + Destructor. +*/ +Sketch::~Sketch() +{ + +} + + +/*! + Constructor. + + \param V3d_Viewer +*/ +Sketch::Sketch(const Handle(V3d_Viewer)& aViewer) : +myInteractiveContext(new AIS_InteractiveContext(aViewer)), +myAxisColor(Quantity_Color(Quantity_NOC_YELLOW)), +myCurrentColor(Quantity_Color(Quantity_NOC_GREEN)), +myWireColor(Quantity_Color(Quantity_NOC_RED)) +{ + Init(); +} + +/*! + Constructor. + + \param V3d_Viewer + \param Quantity_Color + \param Quantity_Color + \param Quantity_Color +*/ +Sketch::Sketch(const Handle(V3d_Viewer)& aViewer, + const Quantity_Color& anAxisColor, + const Quantity_Color& aCurrentColor, + const Quantity_Color& aWireColor): +myInteractiveContext(new AIS_InteractiveContext(aViewer)), +myAxisColor(anAxisColor), +myCurrentColor(aCurrentColor), +myWireColor(aWireColor) +{ + Init(); +} + +/*! + Build the current edge in a graphic mode. + The first signature with view coordinates is used to connect to the move event from the user interface. + The second signature is used when the current point is known by 2d real coordinates. + + \param Xp + \param Yp + \param V3d_View +*/ +void Sketch::MakeCurrentEdge(const Standard_Integer Xp , + const Standard_Integer Yp , + const Handle(V3d_View)& aView ) +{ + /* 3d coordinates of the picked point */ + Standard_Real Xv,Yv,Zv; + aView->Convert(Xp,Yp,Xv,Yv,Zv); + /* computation of real 2d coordinates in plane of sketch */ + Standard_Real Vx,Vy,Vz; + aView->Proj(Vx,Vy,Vz); + gp_Dir D(Vx,Vy,Vz); + gp_Pnt P(Xv,Yv,Zv); + gp_Lin L(P,D); + Standard_Real X,Y; + gp_Pnt Sol; + IntAna_IntConicQuad Int(L,myPlane->Pln(),Precision::Angular()); + if (Int.IsDone()) { + if (!Int.IsParallel()) { + if (Int.NbPoints() > 0 ) { + Sol = Int.Point(1); + ElSLib::Parameters(myPlane->Pln(),Sol,X,Y); + } + } + } + MakeCurrentEdge(X,Y); +} + +/*! + Build the current edge in a graphic mode. + The first signature with view coordinates is used to connect to the move event from the user interface. + The second signature is used when the current point is known by 2d real coordinates. + + \param X + \param Y +*/ +void Sketch::MakeCurrentEdge(const Standard_Real X, const Standard_Real Y) +{ + /* Create the current edge depending on the active mode */ + switch (myCurrentStatus) { + case BEGIN_SKETCH: + myCurrentEdge = BRepBuilderAPI_MakeVertex(ElCLib::To3d(myPlane->Pln().Position().Ax2(),gp_Pnt2d(X,Y))); + break; + case SEGMENT: + MakeCurrentSegment(X,Y); + break; + case ARC_CHORD: + MakeCurrentSegment(X,Y); + break; + case ARC_CHORD_END: + MakeCurrentArc(X,Y); + break; + } + DisplayCurrentEdge(); +} + +/*! + Build the current edge in a graphic mode. + Function to connect to the input event from the user interface. +*/ +void Sketch::ValidateEdge() +{ + gp_Pnt pt; + gp_Pnt2d pt2d; + switch (myCurrentStatus) { + case BEGIN_SKETCH: + { + myFirstPointSketch = TopoDS::Vertex(myCurrentEdge); + myPresentableWire = new AIS_Shape(myFirstPointSketch); + myPresentableWire->SetColor(myWireColor.Name()); + myInteractiveContext->Display(myPresentableWire); + pt = BRep_Tool::Pnt(myFirstPointSketch); + pt2d = ProjLib::Project(myPlane->Pln(),pt); + myLastX = pt2d.X(); + myLastY = pt2d.Y(); + myCurrentStatus = SEGMENT; + break; + } + case SEGMENT: + { + Standard_Real first,last; + TopLoc_Location L; + Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(TopoDS::Edge(myCurrentEdge),myPlane,L,first,last); + myCurrentEdge = BRepBuilderAPI_MakeEdge2d(Handle(Geom2d_Line)::DownCast(C)->Lin2d(),0.,myLengthDimension->Value()); + if (myTransitionStatus == ANGLE || + myTransitionStatus == LENGTH_FIXED || + myTransitionStatus == X_FIXED || + myTransitionStatus == Y_FIXED) + myTransitionStatus = NOCONSTRAINT; + AddEdgeToWire(); + break; + } + case ARC_CHORD: + { + myInteractiveContext->CloseLocalContext(); + myInteractiveContext->OpenLocalContext(); + gp_Pnt2d p1 (myLastX,myLastY); + pt = BRep_Tool::Pnt(TopExp::LastVertex(TopoDS::Edge(myCurrentEdge))); + gp_Pnt2d p2 = ProjLib::Project(myPlane->Pln(),pt); + GccAna_Pnt2dBisec ComputeMediatrice(p1,p2); + if (ComputeMediatrice.HasSolution()) { + myMediatrice = new Geom2d_Line(ComputeMediatrice.ThisSolution()); + Handle(Geom_Curve) aMediatrice3d = GeomAPI::To3d(myMediatrice,myPlane->Pln()); + myPresentableMediatrice = new AIS_Axis(Handle(Geom_Line)::DownCast(aMediatrice3d)); + myInteractiveContext->Display(myPresentableMediatrice); + } + TopoDS_Edge e = BRepBuilderAPI_MakeEdge2d(gce_MakeCirc2d(gp_Pnt2d(0.,0),1.)); + BRepLib::BuildCurve3d(e); + myLengthDimension->SetText(TCollection_ExtendedString()); + myInteractiveContext->Redisplay(myLengthDimension,Standard_False); + if (myEdgesNumber == 0) + myPreviousEdge = TopoDS::Edge(myCurrentEdge); + pt2d = ProjLib::Project(myPlane->Pln(),pt); + myLastX = pt2d.X(); + myLastY = pt2d.Y(); + myTransitionStatus = NOCONSTRAINT; + myCurrentStatus = ARC_CHORD_END; + break; + } + case ARC_CHORD_END: + myCurrentStatus = ARC_CHORD; + AddEdgeToWire(); + break; + } +} + +/*! + Add edge to current wire on an edge validation . +*/ +void Sketch::AddEdgeToWire() +{ + myPreviousEdge = TopoDS::Edge(myCurrentEdge); + BRepLib::BuildCurve3d(myPreviousEdge); + myCurrentWire.Add(TopoDS::Edge(myPreviousEdge)); + myEdgesNumber++; + myPresentableWire->Set( myCurrentWire.Wire() ); + myInteractiveContext->Redisplay(myPresentableWire); + myConstructionMode.Append(myCurrentStatus); + myConstraintMode.Append(myTransitionStatus); + myInteractiveContext->CloseLocalContext(); + gp_Pnt pt; + if (myPreviousEdge.Orientation() == TopAbs_FORWARD ) + pt = BRep_Tool::Pnt(TopExp::LastVertex(TopoDS::Edge(myPreviousEdge))); + else + pt = BRep_Tool::Pnt(TopExp::FirstVertex(TopoDS::Edge(myPreviousEdge))); + gp_Pnt2d pt2d= ProjLib::Project(myPlane->Pln(),pt); + myLastX = pt2d.X(); + myLastY = pt2d.Y(); +} + +/*! + Set the numeric dimension for the current edge and validate creation. + + \param aValue + \return Standard_Boolean +*/ +Standard_Boolean Sketch::SetDimension(Standard_Real& aValue) +{ + fitInResol(aValue); + if (myCurrentStatus == SEGMENT || + myCurrentStatus == ARC_CHORD){ + Standard_Real first,last; + TopLoc_Location L; + Handle(Geom2d_Curve) C = + BRep_Tool::CurveOnSurface(TopoDS::Edge(myCurrentEdge),myPlane,L,first,last); + myCurrentEdge = + BRepBuilderAPI_MakeEdge2d(Handle(Geom2d_Line)::DownCast(C)->Lin2d(),0.,aValue); + DisplayCurrentEdge(); + if (myTransitionStatus == NOCONSTRAINT) { + mySegmentLength = aValue; + myTransitionStatus = LENGTH_FIXED; + } + else + ValidateEdge(); + return Standard_True; + } + + else if( myCurrentStatus == ARC_CHORD_END){ + if (myTransitionStatus == TANGENT) return Standard_False; + gp_Pnt2d p; + if (myEdgesNumber > 0) { + if (myPreviousEdge.Orientation() == TopAbs_FORWARD) + p = ProjLib::Project(myPlane->Pln(),BRep_Tool::Pnt(TopExp::LastVertex(myPreviousEdge))); + else + p = ProjLib::Project(myPlane->Pln(),BRep_Tool::Pnt(TopExp::FirstVertex(myPreviousEdge))); + } + else + p = ProjLib::Project(myPlane->Pln(),BRep_Tool::Pnt(myFirstPointSketch)); + GccAna_Circ2d2TanRad aSol(p, gp_Pnt2d(myLastX,myLastY),aValue,Precision::Confusion()); + Standard_Real dist = RealLast(); + if (aSol.NbSolutions() > 0) { + gp_Circ2d CirSol; + gp_Pnt2d pc = ProjLib::Project(myPlane->Pln(),BRep_Tool::Pnt(TopoDS::Vertex(myCenterCircle->Shape()))); + for (Standard_Integer i =1; i<= aSol.NbSolutions(); i++) { + if (pc.Distance(aSol.ThisSolution(i).Location()) < dist) + CirSol = aSol.ThisSolution(i); + } + if (myCurrentEdge.Orientation() == TopAbs_FORWARD) + myCurrentEdge = BRepBuilderAPI_MakeEdge2d(aSol.ThisSolution(1),p,gp_Pnt2d(myLastX,myLastY)); + else { + myCurrentEdge = BRepBuilderAPI_MakeEdge2d(aSol.ThisSolution(1),gp_Pnt2d(myLastX,myLastY),p); + myCurrentEdge.Reverse(); + } + DisplayCurrentEdge(); + ValidateEdge(); + return Standard_True; + } + } + + return Standard_False; +} + +/*! + Set the numeric dimension for the current edge and validate creation. + + \param deltaX + \param deltaY +*/ +void Sketch::SetDimension(Standard_Real& deltaX, Standard_Real& deltaY) +{ + fitInResol(deltaX); + fitInResol(deltaY); + Standard_Real X = myLastX + deltaX; + Standard_Real Y = myLastY + deltaY; + MakeCurrentEdge(X,Y); + ValidateEdge(); +} + +/*! + Set the numeric value of the X coordinate of current point giving a deltaX relative to previous point. + + \param deltaX +*/ +void Sketch::SetXDimension(Standard_Real& deltaX) +{ + fitInResol(deltaX); + Standard_Real X = myLastX + deltaX; + Standard_Real Y = myLastY; + if ( deltaX == 0. ) + Y = Y + 100.0 * Precision::Confusion(); + + if (myTransitionStatus == NOCONSTRAINT) { + MakeCurrentEdge(X,Y); + myTransitionStatus = X_FIXED; + mySegmentX = X; + } + else if (myTransitionStatus == Y_FIXED) { + myTransitionStatus = NOCONSTRAINT; + MakeCurrentEdge(X,mySegmentY); + ValidateEdge(); + } + else if (myTransitionStatus == ANGLE) { + myTransitionStatus = NOCONSTRAINT; + Standard_Real angle; + if (0 <= mySegmentAngle && mySegmentAngle<= PI ) + angle = PI - mySegmentAngle; + else + angle = mySegmentAngle - PI; + Y = X*Tan(angle); + MakeCurrentEdge(X,Y); + ValidateEdge(); + } + else + myTransitionStatus = NOCONSTRAINT; +} + +/*! + Set the numeric value of the Y coordinate of current point giving a deltaY relative to previous point. + + \param deltaY +*/ +void Sketch::SetYDimension(Standard_Real& deltaY) +{ + fitInResol(deltaY); + Standard_Real X = myLastX; + Standard_Real Y = myLastY + deltaY; + + if ( deltaY == 0. ) + X = X + 100.0 * Precision::Confusion(); + + if (myTransitionStatus == NOCONSTRAINT) { + MakeCurrentEdge(X,Y); + myTransitionStatus = Y_FIXED; + mySegmentY = Y; + } + else if (myTransitionStatus == X_FIXED) { + myTransitionStatus = NOCONSTRAINT; + MakeCurrentEdge(mySegmentX,Y); + ValidateEdge(); + } + else if (myTransitionStatus == ANGLE) { + myTransitionStatus = NOCONSTRAINT; + Standard_Real angle; + if (0 <= mySegmentAngle && mySegmentAngle<= PI ) + angle = PI - mySegmentAngle; + else + angle = mySegmentAngle - PI; + X = Y/Tan(angle); + MakeCurrentEdge(X,Y); + ValidateEdge(); + } + else + myTransitionStatus = NOCONSTRAINT; +} + +/*! + Set the numeric value of angle between 2 segments. + + \param aValue +*/ +void Sketch::SetSegmentAngle(Standard_Real& aValue) +{ + if (myEdgesNumber > 0) { + Standard_Real First,Last; + TopLoc_Location L; + Standard_Real angle; + if (0 <= aValue && aValue<= PI ) + angle = PI - aValue; + else + angle = aValue - PI; + Handle (Geom2d_Curve) PreviousCurve = BRep_Tool::CurveOnSurface(myPreviousEdge,myPlane,L,First,Last); + if (PreviousCurve->IsKind(STANDARD_TYPE(Geom2d_Line))) { + Handle (Geom2d_Curve) PreviousCurve = BRep_Tool::CurveOnSurface(TopoDS::Edge(myPreviousEdge),myPlane,L,First,Last); + + GccAna_Lin2dTanObl aSol(gp_Pnt2d(myLastX,myLastY),Handle(Geom2d_Line)::DownCast(PreviousCurve)->Lin2d(),angle); + myCurrentEdge = BRepBuilderAPI_MakeEdge2d(aSol.ThisSolution(1),0.,myLengthDimension->Value()); + } + if (myTransitionStatus == LENGTH_FIXED) { + ValidateEdge(); + } + else if (myTransitionStatus == X_FIXED) { + Standard_Real length = mySegmentX/Cos(angle); + SetDimension(length); + ValidateEdge(); + } + else if (myTransitionStatus == Y_FIXED) { + Standard_Real length = mySegmentY/Sin(angle); + SetDimension(length); + ValidateEdge(); + } + else { + mySegmentAngle = aValue; + myTransitionStatus = ANGLE; + } + } +} + +/*! + Get the angle value between 2 segments. + + \return Standard_Real +*/ +Standard_Real Sketch::GetSegmentAngle() +{ + return mySegmentAngle; +} + +/*! + Close automatically an open sketch. + + \return TopoDS_Wire. Return null shape if not possible. +*/ +TopoDS_Wire Sketch::Close() +{ + myCurrentStatus = END_SKETCH; + myInteractiveContext->CloseAllContexts(); + myInteractiveContext->EraseAll(Standard_False); + if (myEdgesNumber >= 2) { + BRepTools_WireExplorer Ex(myCurrentWire.Wire()); + TopoDS_Vertex V1; + if (myPreviousEdge.Orientation() == TopAbs_FORWARD) + V1 = TopExp::LastVertex(myPreviousEdge); + else + V1 = TopExp::FirstVertex(myPreviousEdge); + myCurrentWire.Add(BRepBuilderAPI_MakeEdge(V1,myFirstPointSketch).Edge()); + myEdgesNumber++; + return myCurrentWire.Wire(); + } + else + return TopoDS_Wire(); +} + + + +/*! + Clear sketch presentation. +*/ +void Sketch::Clear() +{ + myCurrentStatus = END_SKETCH; + myInteractiveContext->CloseAllContexts(); + myInteractiveContext->EraseAll(Standard_False); +} + +/*! + Terminate sketch without closing. + + \return TopoDS_Wire. Return null shape if not possible. +*/ +TopoDS_Wire Sketch::End() +{ + myCurrentStatus = END_SKETCH; + myInteractiveContext->CloseAllContexts(); + myInteractiveContext->EraseAll(Standard_False); + if (myCurrentWire.IsDone()) { + return myCurrentWire.Wire(); + } + else + return TopoDS_Wire(); +} + + +/*! + Delete current edge. +*/ +Standard_Boolean Sketch::Delete() +{ + myInteractiveContext->Erase(myAngleDimension,Standard_True,Standard_False); + myInteractiveContext->Erase(myLengthDimension,Standard_True,Standard_False); + myInteractiveContext->Erase(myRadiusDimension,Standard_True,Standard_False); + myInteractiveContext->Erase(myCenterCircle,Standard_True,Standard_False); + myInteractiveContext->Erase(myXDimension,Standard_True,Standard_False); + myInteractiveContext->Erase(myYDimension,Standard_True,Standard_False); + + if (myCurrentStatus == BEGIN_SKETCH) { + myCurrentStatus = END_SKETCH; + myInteractiveContext->CloseAllContexts(); + myInteractiveContext->EraseAll(Standard_False); + return true; + } + else if(myCurrentStatus == SEGMENT || + myCurrentStatus == ARC_CHORD ) { + RemoveLastEdge(); + } + else if(myCurrentStatus == ARC_CHORD_END) { + myCurrentStatus = ARC_CHORD; + myInteractiveContext->CloseAllContexts(); + } + gp_Pnt pt; + if (myEdgesNumber == 0) { + //myInteractiveContext->EraseAll(Standard_False); + ChangeMode(BEGIN_SKETCH); // DCQ + pt = BRep_Tool::Pnt(myFirstPointSketch); + } + else { + if (myPreviousEdge.Orientation() == TopAbs_FORWARD ) + pt = BRep_Tool::Pnt(TopExp::LastVertex(TopoDS::Edge(myPreviousEdge))); + else + pt = BRep_Tool::Pnt(TopExp::FirstVertex(TopoDS::Edge(myPreviousEdge))); + } + gp_Pnt2d pt2d= ProjLib::Project(myPlane->Pln(),pt); + myLastX = pt2d.X(); + myLastY = pt2d.Y(); + + return false; +} + +/*! + Set a specific plane for sketch. + + \param GeomyPlane +*/ +void Sketch::SetPlane(const Handle(Geom_Plane)& aPlane) +{ + myPlane = aPlane; +} + +/*! + Set display parameters. + + \param aColor +*/ +void Sketch::SetWireColor(const Quantity_Color& aColor) +{ + myWireColor = aColor; +} + +/*! + Set display parameters. + + \param aColor +*/ +void Sketch::SetCurrentColor(const Quantity_Color& aColor) +{ + myCurrentColor = aColor; +} + +/*! + Set display parameters. + + \param aColor +*/ +void Sketch::SetAxisColor(const Quantity_Color& aColor) +{ + myAxisColor = aColor; +} + + +/*! + Change mode of construction line. + + \param aMode : SEGMENT, ARC_CHORD. +*/ +void Sketch::ChangeMode(const SketchStatus aMode) +{ + gp_Pnt2d p; + if (myEdgesNumber > 0) { + if (myPreviousEdge.Orientation() == TopAbs_FORWARD) + p = ProjLib::Project(myPlane->Pln(),BRep_Tool::Pnt(TopExp::LastVertex(myPreviousEdge))); + else + p = ProjLib::Project(myPlane->Pln(),BRep_Tool::Pnt(TopExp::FirstVertex(myPreviousEdge))); + myLastX = p.X(); + myLastY = p.Y(); + myInteractiveContext->CloseLocalContext(myInteractiveContext->IndexOfCurrentLocal()); + } + if (!myCurrentStatus == BEGIN_SKETCH) + myCurrentStatus = aMode; /* change the mode only when the sketch is not in state BEGIN_SKETCH, i.d. fist point has been fixed */ + +} + +/*! + Set transition constraint between consecutive edges. + + \param aStatus : NOCONSTRAINT, TANGENT, PERPENDICULAR, ANGLE, LENGTH_FIXED, X_FIXED, Y_FIXED. +*/ +void Sketch::SetTransitionStatus(const TransitionStatus aStatus) +{ + myTransitionStatus = aStatus; +} + +/*! + Set or unset the display of dimensions. + + \param atype + \param OnOff +*/ +void Sketch::SetParameterVisibility(const TypeOfParameter atype, const Standard_Boolean OnOff) +{ + switch (atype) { + case ANGLE_PARAMETER: + myIsAngleDimensionVisible = OnOff; + if (!myIsAngleDimensionVisible && !myAngleDimension.IsNull()) + myInteractiveContext->Erase(myAngleDimension,Standard_True,Standard_False); + //else DCQ + // DisplayCurrentEdge(); + break; + case LENGTH_PARAMETER: + myIsLengthDimensionVisible = OnOff; + if (!myIsLengthDimensionVisible&& !myLengthDimension.IsNull()) + myInteractiveContext->Erase(myLengthDimension,Standard_True,Standard_False); + //else DCQ + // DisplayCurrentEdge(); + break; + case RADIUS_PARAMETER: + myIsRadiusDimensionVisible = OnOff; + if (!myIsRadiusDimensionVisible&& !myRadiusDimension.IsNull()){ + myInteractiveContext->Erase(myRadiusDimension,Standard_True,Standard_False); + myInteractiveContext->Erase(myCenterCircle,Standard_True,Standard_False); + } + //else DCQ + // DisplayCurrentEdge(); + break; + case XVALUE_PARAMETER: + myIsXDimensionVisible = OnOff; + if (!myIsXDimensionVisible&& !myXDimension.IsNull()) + myInteractiveContext->Erase(myXDimension,Standard_True,Standard_False); + break; + case YVALUE_PARAMETER: + myIsYDimensionVisible = OnOff; + if (!myIsYDimensionVisible&& !myYDimension.IsNull()) + myInteractiveContext->Erase(myYDimension,Standard_True,Standard_False); + break; + } +} + +/*! + Hilight parameters. + + \param atype + \param acolor +*/ +void Sketch::HiligthWithColor(const TypeOfParameter atype, const Quantity_NameOfColor acolor) +{ + switch (atype) { + case ANGLE_PARAMETER: + myInteractiveContext->HilightWithColor(myAngleDimension, acolor); + break; + case LENGTH_PARAMETER: + myInteractiveContext->HilightWithColor(myLengthDimension, acolor); + break; + case RADIUS_PARAMETER: + myInteractiveContext->HilightWithColor(myRadiusDimension, acolor); + break; + case XVALUE_PARAMETER: + myInteractiveContext->HilightWithColor(myXDimension, acolor); + break; + case YVALUE_PARAMETER: + myInteractiveContext->HilightWithColor(myYDimension, acolor); + break; + } +} + + +/*! + Unhilight parameters. + + \param atype +*/ +void Sketch::Unhiligth(const TypeOfParameter atype) +{ + switch (atype) { + case ANGLE_PARAMETER: + myInteractiveContext->Unhilight(myAngleDimension); + break; + case LENGTH_PARAMETER: + myInteractiveContext->Unhilight(myLengthDimension); + break; + case RADIUS_PARAMETER: + myInteractiveContext->Unhilight(myRadiusDimension); + break; + case XVALUE_PARAMETER: + myInteractiveContext->Unhilight(myXDimension); + break; + case YVALUE_PARAMETER: + myInteractiveContext->Unhilight(myYDimension); + break; + } +} + +/*! + Check if the edition of a type of parameter is relevant depending on sketch current status. + + \param atype + \return Standard_Boolean +*/ +Standard_Boolean Sketch::IsValidCurrentParameter(const TypeOfParameter atype) +{ + switch (atype) { + case ANGLE_PARAMETER: + if (myCurrentStatus != SEGMENT && myCurrentStatus != ARC_CHORD) + return Standard_False; + else if (myTransitionStatus == TANGENT || myTransitionStatus == PERPENDICULAR) + return Standard_False; + else if (myEdgesNumber < 1) + return Standard_False; + else { + TopLoc_Location L; + Standard_Real First,Last; + Handle (Geom2d_Curve) PreviousCurve = BRep_Tool::CurveOnSurface(myPreviousEdge,myPlane,L,First,Last); + if (!PreviousCurve->IsKind(STANDARD_TYPE(Geom2d_Line))) + return Standard_False; + } + break; + case LENGTH_PARAMETER: + if (myCurrentStatus != SEGMENT && + myCurrentStatus != ARC_CHORD /*&& + myCurrentStatus != CURVE_POINTS*/ + ) + return Standard_False; + else if (myTransitionStatus == LENGTH_FIXED) + return Standard_False; + break; + case RADIUS_PARAMETER: + if (myCurrentStatus != ARC_CHORD_END) + return Standard_False; + break; + case XVALUE_PARAMETER: + if (myCurrentStatus != SEGMENT && + myCurrentStatus != ARC_CHORD /*&& + myCurrentStatus != CURVE_POINTS*/ + ) + return Standard_False; + else if (myTransitionStatus == X_FIXED) + return Standard_False; + break; + case YVALUE_PARAMETER: + if (myCurrentStatus != SEGMENT && + myCurrentStatus != ARC_CHORD /*&& + myCurrentStatus != CURVE_POINTS*/ + ) + return Standard_False; + else if (myTransitionStatus == Y_FIXED) + return Standard_False; + break; + } + return Standard_True; +} + +/*! + Set a parameter value. + + \param atype + \param aValue +*/ +void Sketch::SetParameterValue(const TypeOfParameter atype, Standard_Real aValue) +{ + switch (atype) { + case ANGLE_PARAMETER: + SetSegmentAngle(aValue); + break; + case LENGTH_PARAMETER: + SetDimension(aValue); + break; + case RADIUS_PARAMETER: + SetDimension(aValue); + break; + case XVALUE_PARAMETER: + SetXDimension(aValue); + break; + case YVALUE_PARAMETER: + SetYDimension(aValue); + break; + } +} + +/*! + Initialisation of sketch parameters or options. +*/ +void Sketch::Init() +{ + myPlane = new Geom_Plane (0.,0.,1.,0.); + CreateConstraints(); + BRepLib::Plane(myPlane); + myEdgesNumber = 0; + myCurrentStatus = BEGIN_SKETCH; + /* In order to update the visulisation of current objects by using Redisplay method from InteractiveContext */ + myCurrentEdge = BRepBuilderAPI_MakeVertex(gp_Pnt(0.,0.,0.)); + myPresentableEdge = new AIS_Shape(myCurrentEdge); + myPresentableEdge->SetColor(myCurrentColor.Name()); + myInteractiveContext->Display(myPresentableEdge); + myTransitionStatus = NOCONSTRAINT; + /* Init for display objects */ + TopoDS_Vertex V1 = BRepBuilderAPI_MakeVertex(gp_Pnt(0.,0.,0.)); + TopoDS_Vertex V2 = BRepBuilderAPI_MakeVertex(gp_Pnt(10.,0.,0.)); + myLengthDimension = new AIS_LengthDimension (V1,V2,myPlane,0.,TCollection_ExtendedString()); + myXDimension = new AIS_LengthDimension (V1,V2,myPlane,0.,TCollection_ExtendedString(),gp_Pnt(),DsgPrs_AS_NONE, + AIS_TOD_Horizontal); + myYDimension = new AIS_LengthDimension (V1,V2,myPlane,0.,TCollection_ExtendedString(),gp_Pnt(),DsgPrs_AS_NONE, + AIS_TOD_Vertical); + myRadiusDimension = new AIS_LengthDimension (V1,V2,myPlane,0.,TCollection_ExtendedString()); + myCenterCircle = new AIS_Shape(V1); + myIsLengthDimensionVisible = Standard_False; + myIsXDimensionVisible = Standard_False; + myIsYDimensionVisible = Standard_False; + myIsRadiusDimensionVisible = Standard_False; +} + +/*! + Build the current segment. + + \param X + \param Y +*/ +void Sketch::MakeCurrentSegment(Standard_Real X, Standard_Real Y) +{ + if (myTransitionStatus == NOCONSTRAINT) + myCurrentEdge = BRepBuilderAPI_MakeEdge2d(gp_Pnt2d(myLastX,myLastY), gp_Pnt2d(X,Y)); + else if (myTransitionStatus == X_FIXED) + myCurrentEdge = BRepBuilderAPI_MakeEdge2d(gp_Pnt2d(myLastX,myLastY),gp_Pnt2d(mySegmentX,Y)); + else if (myTransitionStatus == Y_FIXED) + myCurrentEdge = BRepBuilderAPI_MakeEdge2d(gp_Pnt2d(myLastX,myLastY),gp_Pnt2d(X,mySegmentY)); + else if (myTransitionStatus == TANGENT && myEdgesNumber > 0) { + Standard_Real first,last; + TopLoc_Location L; + Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(myPreviousEdge,myPlane,L,first,last); + gp_Pnt2d p1; + gp_Vec2d Vt; + if (myPreviousEdge.Orientation() == TopAbs_FORWARD) + C->D1(last,p1,Vt); + else + C->D1(first,p1,Vt); + gp_Lin2d aline(p1,Vt); + Geom2dAPI_ProjectPointOnCurve proj(gp_Pnt2d(X,Y),new Geom2d_Line(aline)); + if (proj.NbPoints() > 0) + myCurrentEdge = BRepBuilderAPI_MakeEdge2d(p1,proj.Point(1)); + } + else if (myTransitionStatus == PERPENDICULAR && myEdgesNumber > 0) { + Standard_Real first,last; + TopLoc_Location L; + Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(myPreviousEdge,myPlane,L,first,last); + gp_Pnt2d p1; + gp_Lin2d perpen; + if (myPreviousEdge.Orientation() == TopAbs_FORWARD) + C->D0(last,p1); + else + C->D0(first,p1); + if (C->IsKind(STANDARD_TYPE(Geom2d_Line))) { + GccAna_Lin2dTanPer aSol(p1,Handle(Geom2d_Line)::DownCast(C)->Lin2d()); + perpen = aSol.ThisSolution(1); + } + else if (C->IsKind(STANDARD_TYPE(Geom2d_Circle))) { + GccAna_Lin2dTanPer aSol(p1,Handle(Geom2d_Circle)::DownCast(C)->Circ2d()); + perpen = aSol.ThisSolution(1); + } + Geom2dAPI_ProjectPointOnCurve proj(gp_Pnt2d(X,Y),new Geom2d_Line(perpen)); + if (proj.NbPoints() > 0) + myCurrentEdge = BRepBuilderAPI_MakeEdge2d(p1,proj.Point(1)); + } + else if (myTransitionStatus == ANGLE && myEdgesNumber > 0) { + Standard_Real First,Last; + TopLoc_Location L; + Handle (Geom2d_Curve) PreviousCurve = BRep_Tool::CurveOnSurface(myPreviousEdge,myPlane,L,First,Last); + if (PreviousCurve->IsKind(STANDARD_TYPE(Geom2d_Line))) { + Handle (Geom2d_Curve) PreviousCurve = BRep_Tool::CurveOnSurface(TopoDS::Edge(myPreviousEdge),myPlane,L,First,Last); + Standard_Real angle; + if (0 <= mySegmentAngle && mySegmentAngle<= PI ) + angle = PI - mySegmentAngle; + else + angle = mySegmentAngle - PI; + GccAna_Lin2dTanObl aSol(gp_Pnt2d(myLastX,myLastY),Handle(Geom2d_Line)::DownCast(PreviousCurve)->Lin2d(),angle); + Standard_Real dist = RealLast(); + gp_Pnt2d pt(X,Y),ptproj; + for (Standard_Integer i =1; i<=aSol.NbSolutions(); i++) { + Geom2dAPI_ProjectPointOnCurve proj(pt,new Geom2d_Line(aSol.ThisSolution(i))); + if (pt.Distance(proj.Point(1)) < dist) { + dist = pt.Distance(proj.Point(1)); + ptproj = proj.Point(1); + } + } + myCurrentEdge = BRepBuilderAPI_MakeEdge2d(gp_Pnt2d(myLastX,myLastY),ptproj); + } + } + else if (myTransitionStatus == LENGTH_FIXED && myEdgesNumber > 0) { + Standard_Real First,Last; + TopLoc_Location L; + Handle (Geom2d_Curve) PreviousCurve = BRep_Tool::CurveOnSurface(myPreviousEdge,myPlane,L,First,Last); + if (PreviousCurve->IsKind(STANDARD_TYPE(Geom2d_Line))) { + Handle (Geom2d_Curve) PreviousCurve = BRep_Tool::CurveOnSurface(TopoDS::Edge(myPreviousEdge),myPlane,L,First,Last); + gp_Lin2d aline = gce_MakeLin2d(gp_Pnt2d(myLastX,myLastY), gp_Pnt2d(X,Y)); + myCurrentEdge = BRepBuilderAPI_MakeEdge2d(aline,0.,mySegmentLength); + } + } +} + +/*! + Build the current arc. + + \param X + \param Y +*/ +void Sketch::MakeCurrentArc(Standard_Real X, Standard_Real Y) +{ + gp_Circ2d CircSol; + Standard_Boolean OK(Standard_False); + + if (myTransitionStatus == NOCONSTRAINT) { + GccAna_Circ2d2TanOn aSol(gp_Pnt2d(myLastX,myLastY), gp_Pnt2d(X,Y),myMediatrice->Lin2d(),Precision::Confusion()); + if (aSol.NbSolutions() > 0){ + CircSol = aSol.ThisSolution(1); + OK = Standard_True; + } + } + /* Tangency with previous edge */ + else if (myTransitionStatus == TANGENT && myEdgesNumber > 0) { + Standard_Real first,last; + TopLoc_Location L; + Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(myPreviousEdge,myPlane,L,first,last); + if (C->IsKind(STANDARD_TYPE(Geom2d_Line))){ + GccAna_Circ2d2TanOn aSol(GccEnt::Unqualified(Handle(Geom2d_Line)::DownCast(C)->Lin2d()), gp_Pnt2d(myLastX,myLastY),myMediatrice->Lin2d(),Precision::Confusion()); + if (aSol.NbSolutions() > 0){ + CircSol = aSol.ThisSolution(1); + OK = Standard_True; + } + } + else if (C->IsKind(STANDARD_TYPE(Geom2d_Circle))) { + GccAna_Circ2d2TanOn aSol(GccEnt::Unqualified(Handle(Geom2d_Circle)::DownCast(C)->Circ2d()), gp_Pnt2d(myLastX,myLastY),myMediatrice->Lin2d(),Precision::Confusion()); + if (aSol.NbSolutions() > 0){ + CircSol = aSol.ThisSolution(1); + OK = Standard_True; + } + } + else if(C->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))) { + gp_Pnt2d pc; + gp_Vec2d Vt; + C->D1(last,pc,Vt); + gp_Lin2d alin2d(pc,gp_Dir2d(Vt)); + GccAna_Circ2d2TanOn aSol(GccEnt::Unqualified(alin2d), gp_Pnt2d(myLastX,myLastY),myMediatrice->Lin2d(),Precision::Confusion()); + if (aSol.NbSolutions() > 0){ + CircSol = aSol.ThisSolution(1); + OK = Standard_True; + } + } + } + /* Tangency with the perpendicular to the previous edge */ + else if (myTransitionStatus == PERPENDICULAR && myEdgesNumber > 0) { + Standard_Real first,last; + TopLoc_Location L; + Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(myPreviousEdge,myPlane,L,first,last); + gp_Pnt2d p1; + gp_Lin2d perpen; + if (myPreviousEdge.Orientation() == TopAbs_FORWARD) + C->D0(last,p1); + else + C->D0(first,p1); + if (C->IsKind(STANDARD_TYPE(Geom2d_Line))) { + GccAna_Lin2dTanPer aSol(p1,Handle(Geom2d_Line)::DownCast(C)->Lin2d()); + perpen = aSol.ThisSolution(1); + } + else if (C->IsKind(STANDARD_TYPE(Geom2d_Circle))) { + GccAna_Lin2dTanPer aSol(p1,Handle(Geom2d_Circle)::DownCast(C)->Circ2d()); + perpen = aSol.ThisSolution(1); + } + GccAna_Circ2d2TanOn aSol(GccEnt::Unqualified(perpen), gp_Pnt2d(myLastX,myLastY),myMediatrice->Lin2d(),Precision::Confusion()); + if (aSol.NbSolutions() > 0){ + CircSol = aSol.ThisSolution(1); + OK = Standard_True; + } + } + + gp_Pnt2d p; + if (myEdgesNumber > 0) { + if (myPreviousEdge.Orientation() == TopAbs_FORWARD) + p = ProjLib::Project(myPlane->Pln(),BRep_Tool::Pnt(TopExp::LastVertex(myPreviousEdge))); + else + p = ProjLib::Project(myPlane->Pln(),BRep_Tool::Pnt(TopExp::FirstVertex(myPreviousEdge))); + } + else + p = ProjLib::Project(myPlane->Pln(),BRep_Tool::Pnt(myFirstPointSketch)); + if (OK){ + gp_Vec2d V1(p,gp_Pnt2d(X,Y)); + gp_Vec2d V2(p,gp_Pnt2d(myLastX,myLastY)); + if (V1.Angle(V2) > 0 ) + myCurrentEdge = BRepBuilderAPI_MakeEdge2d(CircSol,p,gp_Pnt2d(myLastX,myLastY)); + else { + myCurrentEdge = BRepBuilderAPI_MakeEdge2d(CircSol,gp_Pnt2d(myLastX,myLastY),p); + myCurrentEdge.Reverse(); + } + } + else { + myCurrentStatus = ARC_CHORD; + myLastX = p.X(); + myLastY = p.Y(); + myInteractiveContext->CloseLocalContext(); + } + +} + +/*! + Display the current edge under construction with it's dimension. +*/ +void Sketch::DisplayCurrentEdge() +{ + myPresentableEdge->Set(myCurrentEdge); + myInteractiveContext->Redisplay(myPresentableEdge); + if (myCurrentStatus == SEGMENT || + myCurrentStatus == ARC_CHORD ) { + /* Length dimension */ + TopoDS_Vertex V1 = TopExp::FirstVertex(TopoDS::Edge(myCurrentEdge)); + TopoDS_Vertex V2 = TopExp::LastVertex(TopoDS::Edge(myCurrentEdge)); + DisplayLengthDimension(V1,V2); + /* Angular dimension */ + DisplayAngleDimension(); + DisplayXDimension(V1,V2); + DisplayYDimension(V1,V2); + } + else if (myCurrentStatus == ARC_CHORD_END ) + DisplayRadiusDimension(); + else { + TopoDS_Vertex V1 = TopoDS::Vertex(myCurrentEdge); + TopoDS_Vertex V2 = BRepBuilderAPI_MakeVertex(gp_Pnt(0.,0.,0.)); + DisplayXDimension(V1,V2); + DisplayYDimension(V1,V2); + } + +} + +/*! + Display the current length dimension. + + \param V1 + \param V2 +*/ +void Sketch::DisplayLengthDimension(const TopoDS_Vertex& V1,const TopoDS_Vertex& V2) +{ + gp_Pnt p1 = BRep_Tool::Pnt(TopoDS::Vertex(V1)); + gp_Pnt p2 = BRep_Tool::Pnt(TopoDS::Vertex(V2)); + Standard_Real length = p1.Distance(p2); + if (length <= Precision::Confusion()) return; + myLengthDimension->SetFirstShape(V1); + myLengthDimension->SetSecondShape(V2); + fitInResol(length); + myLengthDimension->SetValue(length); + QString S; + S.sprintf("%.1f",length); + myLengthDimension->SetText(TCollection_ExtendedString(strdup(S))); + if (myIsLengthDimensionVisible) { + if (myInteractiveContext->IsDisplayed(myLengthDimension)) + myInteractiveContext->Redisplay(myLengthDimension); + else + myInteractiveContext->Display(myLengthDimension); + } +} + +/*! + Display the current X dimension. + + \param V1 + \param V2 +*/ +void Sketch::DisplayXDimension(const TopoDS_Vertex& V1,const TopoDS_Vertex& V2) +{ + if (myTransitionStatus != X_FIXED) { + gp_Pnt p1 = BRep_Tool::Pnt(TopoDS::Vertex(V1)); + gp_Pnt p2 = BRep_Tool::Pnt(TopoDS::Vertex(V2)); + + gp_Lin aline(p1,myPlane->Pln().XAxis().Direction()); + GeomAPI_ProjectPointOnCurve proj(p2,new Geom_Line(aline)); + + gp_Pnt pb = p1; + + if (proj.NbPoints() > 0) { + Standard_Real length = p1.Distance(proj.Point(1)); + if (length <= Precision::Confusion()) return; + myXDimension->SetFirstShape(V1); + myXDimension->SetSecondShape(V2); + fitInResol(length); + myXDimension->SetValue(length); + QString S; + S.sprintf("%.1f",length); + myXDimension->SetText(TCollection_ExtendedString(strdup(S))); + // myXDimension->SetPosition(proj.Point(1)); + pb.BaryCenter(5,proj.Point(1),5); + myXDimension->SetPosition(pb); + if (myIsXDimensionVisible) { + if (myInteractiveContext->IsDisplayed(myXDimension)) + myInteractiveContext->Redisplay(myXDimension); + else + myInteractiveContext->Display(myXDimension); + } + } + } else + myInteractiveContext->Erase(myXDimension,Standard_True,Standard_False); +} + +/*! + Display the current Y dimension. + + \param V1 + \param V2 +*/ +void Sketch::DisplayYDimension(const TopoDS_Vertex& V1,const TopoDS_Vertex& V2) +{ + if (myTransitionStatus != Y_FIXED) { + + gp_Pnt p1 = BRep_Tool::Pnt(TopoDS::Vertex(V1)); + gp_Pnt p2 = BRep_Tool::Pnt(TopoDS::Vertex(V2)); + gp_Lin aline(p2 /*p1*/, myPlane->Pln().YAxis().Direction()); + gp_Pnt pb = p2 /*p1*/; + GeomAPI_ProjectPointOnCurve proj(p1 /*p2*/,new Geom_Line(aline)); + if (proj.NbPoints() > 0) { + Standard_Real length = /*p1*/ p2.Distance(proj.Point(1)); + if (length <= Precision::Confusion()) return; + myYDimension->SetFirstShape(V1); + myYDimension->SetSecondShape(V2); + fitInResol(length); + myYDimension->SetValue(length); + QString S; + S.sprintf("%.1f",length); + myYDimension->SetText(TCollection_ExtendedString(strdup(S))); + pb.BaryCenter(5,proj.Point(1),5); + myYDimension->SetPosition(pb); + // myYDimension->SetPosition(p2); + if (myIsYDimensionVisible) { + if (myInteractiveContext->IsDisplayed(myYDimension)) + myInteractiveContext->Redisplay(myYDimension); + else + myInteractiveContext->Display(myYDimension); + } + } + } else + myInteractiveContext->Erase(myYDimension,Standard_True,Standard_False); +} + +/*! + Display the current angle dimension. +*/ +void Sketch::DisplayAngleDimension() +{ + if (!myIsAngleDimensionVisible) + return; + if (myEdgesNumber > 0) { + Standard_Real First,Last; + TopLoc_Location L; + Handle (Geom2d_Curve) PreviousCurve = BRep_Tool::CurveOnSurface(myPreviousEdge,myPlane,L,First,Last); + Handle (Geom2d_Curve) CurrentCurve = BRep_Tool::CurveOnSurface(TopoDS::Edge(myCurrentEdge),myPlane,L,First,Last); + if (PreviousCurve->IsKind(STANDARD_TYPE(Geom2d_Line)) && CurrentCurve->IsKind(STANDARD_TYPE(Geom2d_Line))) { + Standard_Real angle = Handle(Geom2d_Line)::DownCast(PreviousCurve)->Lin2d().Angle(Handle(Geom2d_Line)::DownCast(CurrentCurve)->Lin2d()); + gp_Pnt2d apos; + if (0 <= angle && angle<= PI) + angle = PI - angle; + else + angle = PI + angle; + CurrentCurve->D0((First+Last)/5.,apos); + gp_Pnt apos3d = ElCLib::To3d(myPlane->Pln().Position().Ax2(),apos); + Standard_Real angtext = angle*180./PI; + mySegmentAngle = angle; + BRepLib::BuildCurve3d(TopoDS::Edge(myCurrentEdge)); + fitInResol(angtext); + + QString S; + S.sprintf("%.1f",angtext); + if (myInteractiveContext->IndexOfCurrentLocal() == 0) { + myInteractiveContext->OpenLocalContext(); + myAngleDimension = new AIS_AngleDimension(myPreviousEdge,TopoDS::Edge(myCurrentEdge),myPlane,angle, + TCollection_ExtendedString(strdup(S))); + myInteractiveContext->Display(myAngleDimension); + } + else { + myAngleDimension->SetSecondShape(myCurrentEdge); + myAngleDimension->SetValue(angle); + myAngleDimension->SetPosition(apos3d); + myAngleDimension->SetText(TCollection_ExtendedString(strdup(S))); + myInteractiveContext->Redisplay(myAngleDimension); + } + } + } +} + +/*! + Display the current radius dimension. +*/ +void Sketch::DisplayRadiusDimension() +{ + if (! myIsRadiusDimensionVisible) + return; + BRepLib::BuildCurve3d(TopoDS::Edge(myCurrentEdge)); + Standard_Real First,Last; + Handle (Geom_Circle) C = Handle (Geom_Circle)::DownCast(BRep_Tool::Curve(TopoDS::Edge(myCurrentEdge),First,Last)); + if (!C.IsNull()) { + Standard_Real R = C->Radius(); + TopoDS_Shape V1 = BRepBuilderAPI_MakeVertex(C->Location()); + gp_Pnt MidlePoint ; + C->D0((First+Last)/2.,MidlePoint); + TopoDS_Vertex V2 = BRepBuilderAPI_MakeVertex(MidlePoint); + myRadiusDimension->SetFirstShape(V1); + myRadiusDimension->SetSecondShape(V2); + myRadiusDimension->SetValue(R); + fitInResol(R); + QString S; + S.sprintf("%.1f",R); + myRadiusDimension->SetText(TCollection_ExtendedString(strdup(S))); + if (myInteractiveContext->IsDisplayed(myRadiusDimension)) + myInteractiveContext->Redisplay(myRadiusDimension); + else + myInteractiveContext->Display(myRadiusDimension); + myCenterCircle->Set(V1); + if (myInteractiveContext->IsDisplayed(myCenterCircle)) + myInteractiveContext->Redisplay(myCenterCircle); + else + myInteractiveContext->Display(myCenterCircle); + } +} + +/*! + Remove last edge from the current wire. +*/ +void Sketch::RemoveLastEdge() +{ + if (myEdgesNumber == 0) { + myCurrentStatus = END_SKETCH; + myInteractiveContext->CloseAllContexts(); + myInteractiveContext->EraseAll(Standard_False); + return; + } + else { + BRepTools_WireExplorer Ex; + BRepBuilderAPI_MakeWire MW; + Standard_Integer index = 1; + myCurrentEdge = myPreviousEdge; + for (Ex.Init(myCurrentWire.Wire());Ex.More();Ex.Next()){ + if (index <= myEdgesNumber-1) { + MW.Add(Ex.Current()); + myPreviousEdge = Ex.Current(); + index++; + } + } + myCurrentWire = MW; + myCurrentStatus = (SketchStatus)myConstructionMode(myEdgesNumber); + myTransitionStatus = (TransitionStatus)myConstraintMode(myEdgesNumber); + myEdgesNumber--; + myConstructionMode.Remove(index); + myConstraintMode.Remove(index); + if (myEdgesNumber == 0) + myPresentableWire->Set(myFirstPointSketch); + else + myPresentableWire->Set(myCurrentWire.Wire()); + myInteractiveContext->Redisplay(myPresentableWire); + myInteractiveContext->CloseLocalContext(); + myPresentableEdge->Set(myCurrentEdge); + myInteractiveContext->Redisplay(myPresentableEdge); + } +} + +/*! + Create initial constraints. +*/ +void Sketch::CreateConstraints() +{ + Handle(Geom_Axis1Placement) xAxis = new Geom_Axis1Placement(myPlane->Pln().XAxis()); + Handle(Geom_Axis1Placement) yAxis = new Geom_Axis1Placement(myPlane->Pln().YAxis()); + myHAxis = new AIS_Axis(xAxis); + myVAxis = new AIS_Axis(yAxis); + myAngularAxis = myVAxis; + myHAxis->SetColor(myAxisColor.Name()); + myVAxis->SetColor(myAxisColor.Name()); + myAngularAxis->SetColor(myAxisColor.Name()); +} + +/*! + fitInResol. + + \param toFit + \param minIsResol +*/ +void Sketch::fitInResol(Standard_Real &toFit, Standard_Boolean minIsResol) +{ + Standard_Real sign = (toFit < 0) ? -1. : +1.; + Standard_Real value = toFit + sign * resol/2.0; /* why "+ resol/2.0" ? because if resol = 0.5, 3.3 is rounded to 3.5 */ + int nTimesResol = int(value/resol); + if ((nTimesResol == 0) && (minIsResol)) nTimesResol = 1; + toFit = nTimesResol*resol; +} + +SketchStatus Sketch::GetCurrentStatus() +{ + return myCurrentStatus; +} + +Standard_Integer Sketch::GetmyEdgesNumber() +{ + return myEdgesNumber; +} + + + diff --git a/SKETCHER/GEOM_Sketcher.h b/SKETCHER/GEOM_Sketcher.h new file mode 100644 index 000000000..89b12c086 --- /dev/null +++ b/SKETCHER/GEOM_Sketcher.h @@ -0,0 +1,201 @@ +// GEOM SKETCHER : basic sketcher +// +// 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 +// +// +// +// File : GEOM_Sketcher.h +// Author : Nicolas REJNERI +// Module : GEOM +// $Header$ + +#include "GEOM_SketcherStatus.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class Sketch +{ +public: + Sketch(); + ~Sketch(); + Sketch(const Handle(V3d_Viewer)& aViewer); + Sketch(const Handle(V3d_Viewer)& aViewer, + const Quantity_Color& anAxisColor, + const Quantity_Color& aCurrentColor, + const Quantity_Color& aWireColor); + + static void fitInResol(Standard_Real &toFit, + Standard_Boolean minIsResol = Standard_False); + + void MakeCurrentEdge(const Standard_Integer Xp , + const Standard_Integer Yp , + const Handle(V3d_View)& aView ); + + void MakeCurrentEdge(const Standard_Real X, const Standard_Real Y); + + Standard_Boolean SetDimension(Standard_Real& aValue); + void SetDimension(Standard_Real& deltaX,Standard_Real& deltaY); + + void SetXDimension(Standard_Real& deltaX); + void SetYDimension(Standard_Real& deltaY); + + void SetSegmentAngle(Standard_Real& aValue); + Standard_Real GetSegmentAngle(); + + void ValidateEdge(); + + TopoDS_Wire Close(); + TopoDS_Wire End(); + + void Clear(); + + Standard_Boolean Delete(); + + void SetPlane(const Handle(Geom_Plane)& aPlane); + + void SetWireColor(const Quantity_Color& aColor); + void SetCurrentColor(const Quantity_Color& aColor); + void SetAxisColor(const Quantity_Color& aColor); + + void SetParameterVisibility(const TypeOfParameter atype, + const Standard_Boolean OnOff); + + void HiligthWithColor(const TypeOfParameter atype, + const Quantity_NameOfColor acolor); + void Unhiligth(const TypeOfParameter atype); + + Standard_Boolean IsValidCurrentParameter(const TypeOfParameter atype); + + void SetParameterValue(const TypeOfParameter atype, Standard_Real aValue); + + void ChangeMode(const SketchStatus aMode); + + void SetTransitionStatus(const TransitionStatus aStatus); + + SketchStatus GetCurrentStatus(); + Standard_Integer GetmyEdgesNumber(); + +private : + + void Init(); + + void MakeCurrentSegment(Standard_Real X, Standard_Real Y); + + void MakeCurrentArc(Standard_Real X, Standard_Real Y); + + void DisplayCurrentEdge(); + + void DisplayLengthDimension(const TopoDS_Vertex& V1,const TopoDS_Vertex& V2); + void DisplayXDimension(const TopoDS_Vertex& V1,const TopoDS_Vertex& V2); + void DisplayYDimension(const TopoDS_Vertex& V1,const TopoDS_Vertex& V2); + void DisplayAngleDimension(); + void DisplayRadiusDimension(); + + void AddEdgeToWire(); + + void RemoveLastEdge(); + + void CreateConstraints(); + +private: + // Current status of construction + SketchStatus myCurrentStatus; + // Transition status between arcs and segments + TransitionStatus myTransitionStatus; + // Current wire + BRepBuilderAPI_MakeWire myCurrentWire; + // Current presentable wire + Handle_AIS_Shape myPresentableWire; + // Number of edges into the current wire + Standard_Integer myEdgesNumber; + // Store for each edge how it has been built i.d the value of myCurrentStatus + TColStd_SequenceOfInteger myConstructionMode; + // Store for each edge how it has been built i.d the value of myTransitionStatus + TColStd_SequenceOfInteger myConstraintMode; + // Current edge + TopoDS_Shape myCurrentEdge; + // Previous edge + TopoDS_Edge myPreviousEdge; + // List of points to interpolate when computing a curve by interpolation + TColgp_SequenceOfPnt2d myPointsToInterpolate; + // Tangent vector at beginning of curve + gp_Vec2d myTangentVector; + // Tangent flag at beginning og curve + Standard_Boolean myTangentFlag; + + // Origin of sketch + TopoDS_Vertex myFirstPointSketch; + // Last x coordinate of end point of previous edge or picked point + Standard_Real myLastX; + // Last y coordinate of end point of previous edge or picked point + Standard_Real myLastY; + // angle between 2 segments when an ANGLE TransitionStatus is set. + Standard_Real mySegmentAngle; + // Length of segment when the length of the segment is fixed before the angle + Standard_Real mySegmentLength; + // Value of X fixed coordinate + Standard_Real mySegmentX; + // Value of Y fixed Coordinate + Standard_Real mySegmentY; + Handle_AIS_Shape myPresentableEdge; // Current presentable edge + Handle_AIS_LengthDimension myLengthDimension;// For display of current length segment dimension + Handle_AIS_LengthDimension myXDimension; // For display of current X segment dimension + Handle_AIS_LengthDimension myYDimension; // For display of current Y segment dimension + Handle_AIS_LengthDimension myRadiusDimension;// For display of current radius dimension + Handle_AIS_AngleDimension myAngleDimension; // For display of current angle dimension + Standard_Boolean myIsLengthDimensionVisible; // Visibility flag for LengthDimension + Standard_Boolean myIsXDimensionVisible; // Visibility flag for X Dimension + Standard_Boolean myIsYDimensionVisible; // Visibility flag for Y Dimension + Standard_Boolean myIsRadiusDimensionVisible; // Visibility flag for RadiusDimension + Standard_Boolean myIsAngleDimensionVisible; // Visibility flag for AngleDimension + Handle_AIS_Axis myPresentableMediatrice; // Chord mediatrice of current circle as a presentable object + Handle_Geom2d_Line myMediatrice; // Chord mediatrice of current circle as a 2d line + Handle_AIS_Shape myCenterCircle; // to visualise center of current arc + + Handle_AIS_Axis myHAxis; // Horizontal axis + Handle_AIS_Axis myVAxis; // Vertical axis + Handle_AIS_Axis myAngularAxis; // Axis making a predefined angle with the previous edge + + Quantity_Color myWireColor; // Color of wire and of build edges + Quantity_Color myCurrentColor; // Color of edge under construction + Quantity_Color myAxisColor; // Color for axis + Handle_AIS_InteractiveContext myInteractiveContext; // Interactive context for display management + + Handle_Geom_Plane myPlane; // Plane of sketch + + BRepBuilderAPI_MakeWire myPasteWire; + Standard_Integer myPasteEdgesNumber; + TColStd_SequenceOfInteger myPasteConstructionMode; + TColStd_SequenceOfInteger myPasteConstraintMode; +}; diff --git a/SKETCHER/GEOM_SketcherStatus.h b/SKETCHER/GEOM_SketcherStatus.h new file mode 100644 index 000000000..4e3adbc1a --- /dev/null +++ b/SKETCHER/GEOM_SketcherStatus.h @@ -0,0 +1,53 @@ +// GEOM SKETCHER : basic sketcher +// +// 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 +// +// +// +// File : GEOM_SketcherStatus.h +// Author : Nicolas REJNERI +// Module : GEOM +// $Header$ + +enum TransitionStatus { + NOCONSTRAINT, // no constraint between consecutive edges + TANGENT, // arc and segment are tangent + PERPENDICULAR,// arc is tangent to the perpendicular to the segment + ANGLE, // Angular constraint between 2 segments + LENGTH_FIXED, // Length of segment has been fixed + X_FIXED, // X coordinate for segment has been fixed + Y_FIXED // Y coordinate for segment has been fixed + }; + +enum TypeOfParameter { + ANGLE_PARAMETER, + LENGTH_PARAMETER, + RADIUS_PARAMETER, + XVALUE_PARAMETER, + YVALUE_PARAMETER + }; + +enum SketchStatus { + BEGIN_SKETCH, // Begin sketch; no edges created yet + SEGMENT, // Current mode for creation is segment + ARC_CHORD, // Current mode for creation is arc by chord + ARC_CHORD_END,// Chord validated, waiting for radius or center + END_SKETCH // End sketch +}; diff --git a/SKETCHER/Makefile.in b/SKETCHER/Makefile.in new file mode 100644 index 000000000..9de74619f --- /dev/null +++ b/SKETCHER/Makefile.in @@ -0,0 +1,58 @@ +# GEOM SKETCHER : basic sketcher +# +# 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 +# +# +# +# File : Makefile.in +# Author : Patrick GOLDBRONN (CEA) +# Module : GEOM +# $Header$ + +top_srcdir=@top_srcdir@ +top_builddir=../../.. +srcdir=@srcdir@ +VPATH=.:@srcdir@:@top_srcdir@/idl + + +@COMMENCE@ + +# Libraries targets + +LIB = libGeometrySketcher.la +LIB_SRC = GEOM_Sketcher.cxx +LIB_CLIENT_IDL = SALOME_Component.idl SALOMEDS.idl SALOME_Exception.idl GEOM_Shape.idl GEOM_Gen.idl + +# header files +EXPORT_HEADERS= GEOM_Sketcher.h \ + GEOM_SketcherStatus.h + +# additionnal information to compil and link file +CPPFLAGS += $(OCC_INCLUDES) $(QT_INCLUDES) +CXXFLAGS += $(OCC_CXXFLAGS) +LDFLAGS += $(OCC_LIBS) + +# additional file to be cleaned +MOSTLYCLEAN = +CLEAN = +DISTCLEAN = + +@CONCLUDE@ +