From ecab0565f548a86a92f1b1472de15db606e88652 Mon Sep 17 00:00:00 2001 From: jfa Date: Wed, 24 Oct 2007 06:48:22 +0000 Subject: [PATCH] NPAL14856: Get The Normal of a Face. And merge MakePipeShellsWithoutPath from 3.2.X. --- idl/GEOM_Gen.idl | 27 +- idl/GEOM_Superv.idl | 3 + resources/Makefile.am | 1 + resources/normale.png | Bin 0 -> 260 bytes src/GEOMGUI/GEOM_images.po | 8 +- src/GEOMGUI/GEOM_msg_en.po | 20 + src/GEOMGUI/GeometryGUI.cxx | 3 + src/GEOMImpl/GEOMImpl_I3DPrimOperations.cxx | 149 +++ src/GEOMImpl/GEOMImpl_I3DPrimOperations.hxx | 4 + src/GEOMImpl/GEOMImpl_IMeasure.hxx | 12 +- src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx | 64 + src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx | 3 + src/GEOMImpl/GEOMImpl_MeasureDriver.cxx | 106 +- src/GEOMImpl/GEOMImpl_PipeDriver.cxx | 1224 +++++++++++++++--- src/GEOMImpl/GEOMImpl_Types.hxx | 1 + src/GEOM_I/GEOM_I3DPrimOperations_i.cc | 56 +- src/GEOM_I/GEOM_I3DPrimOperations_i.hh | 3 + src/GEOM_I/GEOM_IMeasureOperations_i.cc | 37 +- src/GEOM_I/GEOM_IMeasureOperations_i.hh | 3 + src/GEOM_I_Superv/GEOM_Superv_i.cc | 19 + src/GEOM_I_Superv/GEOM_Superv_i.hh | 3 + src/GEOM_SWIG/GEOM_TestMeasures.py | 16 + src/GEOM_SWIG/geompyDC.py | 68 +- src/MeasureGUI/Makefile.am | 2 + src/MeasureGUI/MeasureGUI.cxx | 2 + src/MeasureGUI/MeasureGUI_NormaleDlg.cxx | 281 ++++ src/MeasureGUI/MeasureGUI_NormaleDlg.h | 74 ++ 27 files changed, 2006 insertions(+), 183 deletions(-) create mode 100644 resources/normale.png create mode 100644 src/MeasureGUI/MeasureGUI_NormaleDlg.cxx create mode 100644 src/MeasureGUI/MeasureGUI_NormaleDlg.h diff --git a/idl/GEOM_Gen.idl b/idl/GEOM_Gen.idl index 9c161c2e3..fa99c0db3 100644 --- a/idl/GEOM_Gen.idl +++ b/idl/GEOM_Gen.idl @@ -910,7 +910,15 @@ module GEOM in GEOM_Object thePath, in boolean theWithContact , in boolean theWithCorrection ); - + + /*! + * Create solids between given sections + * \param theSeqBases - list of sections (shell or face). + * \param theLocations - list of corresponding vertexes + * \return New GEOM_Object, containing the created solids. + */ + GEOM_Object MakePipeShellsWithoutPath (in ListOfGO theSeqBases, + in ListOfGO theLocations); }; /*! @@ -1792,7 +1800,7 @@ module GEOM GEOM_Object MakeCircleThreePnt (in GEOM_Object thePnt1, in GEOM_Object thePnt2, in GEOM_Object thePnt3); -/*! + /*! * Create a circle with given center, with a radius equals the distance from center to Point1 * and on a plane defined by all of three points. * \param thePnt1,thePnt2,thePnt3 Points, defining the circle. @@ -1938,6 +1946,7 @@ module GEOM in double theR1, in double theR2, in ListOfLong theEdges); + /*! * Perform a fillet on all edges of the specified faces of the given shape. * \param theShape Shape, to perform fillet on. @@ -1954,6 +1963,7 @@ module GEOM in double theR1, in double theR2, in ListOfLong theFaces); + /*! * Perform a symmetric chamfer on all edges of the given shape. * \param theShape Shape, to perform chamfer on. @@ -1984,6 +1994,7 @@ module GEOM GEOM_Object MakeChamferEdgeAD (in GEOM_Object theShape, in double theD, in double theAngle, in long theFace1, in long theFace2); + /*! * Perform a chamfer on all edges of the specified faces. * with distance D1 on the first specified face (if several for one edge) @@ -2026,6 +2037,7 @@ module GEOM GEOM_Object MakeChamferEdgesAD (in GEOM_Object theShape, in double theD, in double theAngle, in ListOfLong theEdges); + /*! * Perform an Archimde operation on the given shape with given parameters. * The object presenting the resulting face is returned @@ -2331,6 +2343,17 @@ module GEOM */ GEOM_Object GetCentreOfMass (in GEOM_Object theShape); + /*! + * Get a vector, representing the normal of theFace. + * If the face is not planar, theOptionalPoint is obligatory. + * \param theFace Shape (face) to define the normal of. + * \param theOptionalPoint Shape (point) to define the normal at. + * Can be NULL in case of planar face. + * \return New GEOM_Object, containing the created normal vector. + */ + GEOM_Object GetNormal (in GEOM_Object theFace, + in GEOM_Object theOptionalPoint); + /*! * Get inertia matrix and moments of inertia of theShape. * \param theShape Shape to calculate inertia of. diff --git a/idl/GEOM_Superv.idl b/idl/GEOM_Superv.idl index 7eaab4b6c..e217d4077 100644 --- a/idl/GEOM_Superv.idl +++ b/idl/GEOM_Superv.idl @@ -184,6 +184,9 @@ module GEOM in boolean theWithContact , in boolean theWithCorrection ); + GEOM_Object MakePipeShellsWithoutPath (in ListOfGO theSeqBases, + in ListOfGO theLocations ); + //-----------------------------------------------------------// // BooleanOperations // //-----------------------------------------------------------// diff --git a/resources/Makefile.am b/resources/Makefile.am index 9db099085..50a623104 100644 --- a/resources/Makefile.am +++ b/resources/Makefile.am @@ -98,6 +98,7 @@ multirotationsimple.png \ multitranslation.png \ multitranslationdouble.png \ multitranslationsimple.png \ +normale.png \ offset.png \ orientation.png \ partition.png \ diff --git a/resources/normale.png b/resources/normale.png new file mode 100644 index 0000000000000000000000000000000000000000..7db7fb21f1f19efcda943b8a174188d6098f6ba7 GIT binary patch literal 260 zcmV+f0sH=mP)~C|XEw$}B(4wVn7(Qd98f+>*ETKcrUpKN z>ImbMhsI`Rh)8&qDuIZAQ-;Y6sU8CW%{mx_>eidwbT87`U%(f{8a~oYCyo370000< KMNUMnLSTZmLTv^B literal 0 HcmV?d00001 diff --git a/src/GEOMGUI/GEOM_images.po b/src/GEOMGUI/GEOM_images.po index f968ecac8..157ec0807 100644 --- a/src/GEOMGUI/GEOM_images.po +++ b/src/GEOMGUI/GEOM_images.po @@ -209,6 +209,10 @@ msgstr "partitionplane.png" msgid "ICON_DLG_CENTERMASS" msgstr "centergravity.png" +#NormaleDlg +msgid "ICON_DLG_NORMALE" +msgstr "normale.png" + #BoundingBoxDlg msgid "ICON_DLG_BOUNDING_BOX" msgstr "bounding.png" @@ -738,8 +742,8 @@ msgstr "point_coord.png" msgid "ICO_BASIC_PROPS" msgstr "basicproperties.png" -msgid "ICO_MASS_CENTER" -msgstr "centergravity.png" +msgid "ICO_NORMALE" +msgstr "normale.png" msgid "ICO_INERTIA" msgstr "axisinertia.png" diff --git a/src/GEOMGUI/GEOM_msg_en.po b/src/GEOMGUI/GEOM_msg_en.po index 958384b10..8db6a7dc9 100644 --- a/src/GEOMGUI/GEOM_msg_en.po +++ b/src/GEOMGUI/GEOM_msg_en.po @@ -588,6 +588,13 @@ msgstr "Bounding Box" msgid "GEOM_CMASS" msgstr "Center Of Mass" +#Normale +msgid "GEOM_NORMALE" +msgstr "Normale To A Face" + +msgid "GEOM_VECTOR_NORMALE" +msgstr "Vector_Normale" + #Basic Properties msgid "GEOM_PROPERTIES" msgstr "Basic Properties" @@ -862,6 +869,10 @@ msgstr "Circle Construction" msgid "GEOM_CMASS_TITLE" msgstr "Center Of Mass Construction" +#: GeometryGUI_NormaleDlg.cxx:57 +msgid "GEOM_NORMALE_TITLE" +msgstr "Create Normale To A Face" + msgid "GEOM_PLANE_SIZE" msgstr "Size of plane :" @@ -2727,6 +2738,15 @@ msgstr "Center of mass" msgid "STB_MASS_CENTER" msgstr "Compute center of mass" +msgid "TOP_NORMALE" +msgstr "Compute normale to a face" + +msgid "MEN_NORMALE" +msgstr "Normale to a face" + +msgid "STB_NORMALE" +msgstr "Compute normale to a face in a point (optional)" + msgid "TOP_INERTIA" msgstr "Compute intertia" diff --git a/src/GEOMGUI/GeometryGUI.cxx b/src/GEOMGUI/GeometryGUI.cxx index 3bcaac292..f72ed036b 100644 --- a/src/GEOMGUI/GeometryGUI.cxx +++ b/src/GEOMGUI/GeometryGUI.cxx @@ -524,6 +524,7 @@ void GeometryGUI::OnGUIEvent( int id ) else if( id == 701 || // MENU MEASURE - PROPERTIES id == 702 || // MENU MEASURE - CDG id == 703 || // MENU MEASURE - INERTIA + id == 704 || // MENU MEASURE - NORMALE id == 7041 || // MENU MEASURE - BOUNDING BOX id == 7042 || // MENU MEASURE - MIN DISTANCE id == 7043 || // MENU MEASURE - ANGLE @@ -847,6 +848,7 @@ void GeometryGUI::initialize( CAM_Application* app ) createGeomAction( 701, "BASIC_PROPS" ); createGeomAction( 702, "MASS_CENTER" ); createGeomAction( 703, "INERTIA" ); + createGeomAction( 704, "NORMALE" ); createGeomAction( 7041, "BND_BOX" ); createGeomAction( 7042, "MIN_DIST" ); createGeomAction( 7043, "MEASURE_ANGLE" ); @@ -1002,6 +1004,7 @@ void GeometryGUI::initialize( CAM_Application* app ) createMenu( separator(), measurId, -1 ); createMenu( 702, measurId, -1 ); createMenu( 703, measurId, -1 ); + createMenu( 704, measurId, -1 ); // NPAL16572: move "Check free boundaries" and "Check free faces" from "Repair" to "Measure" createMenu( separator(), measurId, -1 ); createMenu( 609, measurId, -1 ); diff --git a/src/GEOMImpl/GEOMImpl_I3DPrimOperations.cxx b/src/GEOMImpl/GEOMImpl_I3DPrimOperations.cxx index de70f1259..2571cae0b 100644 --- a/src/GEOMImpl/GEOMImpl_I3DPrimOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_I3DPrimOperations.cxx @@ -1375,6 +1375,23 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeWithShellSections( pyDump<< "], ["; + for(i =1 ; i <= nbSubBases; i++) { + + Handle(Standard_Transient) anItem = theSubBases->Value(i); + if(anItem.IsNull()) + continue; + + Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(anItem); + if(!anObj.IsNull()) { + pyDump<< anObj; + if(i < nbBases) + pyDump<<", "; + } + + } + + pyDump<< "], ["; + for(i =1 ; i <= nbLocs; i++) { Handle(Standard_Transient) anItem = theLocations->Value(i); @@ -1396,3 +1413,135 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeWithShellSections( } + +//============================================================================= +/*! + * MakePipeShellsWithoutPath + */ +//============================================================================= +Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeShellsWithoutPath( + const Handle(TColStd_HSequenceOfTransient)& theBases, + const Handle(TColStd_HSequenceOfTransient)& theLocations) +{ + Handle(GEOM_Object) anObj; + SetErrorCode(KO); + if(theBases.IsNull()) + return anObj; + + Standard_Integer nbBases = theBases->Length(); + + if (!nbBases) + return anObj; + + Standard_Integer nbLocs = (theLocations.IsNull() ? 0 :theLocations->Length()); + + //Add a new Pipe object + Handle(GEOM_Object) aPipeDS = GetEngine()->AddObject(GetDocID(), GEOM_PIPE); + + //Add a new Pipe function + + Handle(GEOM_Function) aFunction = + aPipeDS->AddFunction(GEOMImpl_PipeDriver::GetID(), PIPE_SHELLS_WITHOUT_PATH); + if (aFunction.IsNull()) return anObj; + + //Check if the function is set correctly + if (aFunction->GetDriverGUID() != GEOMImpl_PipeDriver::GetID()) return anObj; + + GEOMImpl_IPipeShellSect aCI (aFunction); + + Handle(TColStd_HSequenceOfTransient) aSeqBases = new TColStd_HSequenceOfTransient; + Handle(TColStd_HSequenceOfTransient) aSeqLocs = new TColStd_HSequenceOfTransient; + + Standard_Integer i =1; + for( ; i <= nbBases; i++) { + + Handle(Standard_Transient) anItem = theBases->Value(i); + if(anItem.IsNull()) + continue; + Handle(GEOM_Object) aBase = Handle(GEOM_Object)::DownCast(anItem); + if(aBase.IsNull()) + continue; + Handle(GEOM_Function) aRefBase = aBase->GetLastFunction(); + if(aRefBase.IsNull()) + continue; + + if(nbLocs) { + Handle(Standard_Transient) anItemLoc = theLocations->Value(i); + if(anItemLoc.IsNull()) + continue; + Handle(GEOM_Object) aLoc = Handle(GEOM_Object)::DownCast(anItemLoc); + if(aLoc.IsNull()) + continue; + Handle(GEOM_Function) aRefLoc = aLoc->GetLastFunction(); + if(aRefLoc.IsNull()) + continue; + aSeqLocs->Append(aRefLoc); + } + + aSeqBases->Append(aRefBase); + } + + if(!aSeqBases->Length()) + return anObj; + + aCI.SetBases(aSeqBases); + aCI.SetLocations(aSeqLocs); + + //Compute the Pipe value + try { +#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 + OCC_CATCH_SIGNALS; +#endif + if (!GetSolver()->ComputeFunction(aFunction)) { + SetErrorCode("Pipe with shell sections without path driver failed"); + return anObj; + } + } + catch (Standard_Failure) { + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + SetErrorCode(aFail->GetMessageString()); + return anObj; + } + + //Make a Python command + GEOM::TPythonDump pyDump(aFunction); + pyDump << aPipeDS << " = geompy.MakePipeShellsWithoutPath(["; + + for(i =1 ; i <= nbBases; i++) { + + Handle(Standard_Transient) anItem = theBases->Value(i); + if(anItem.IsNull()) + continue; + + Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(anItem); + if(!anObj.IsNull()) { + pyDump<< anObj; + if(i < nbBases) + pyDump<<", "; + } + + } + + pyDump<< "], ["; + + for(i =1 ; i <= nbLocs; i++) { + + Handle(Standard_Transient) anItem = theLocations->Value(i); + if(anItem.IsNull()) + continue; + + Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(anItem); + if(!anObj.IsNull()) { + pyDump<< anObj; + if(i < nbLocs) + pyDump<<", "; + } + } + + pyDump<< "])"; + + SetErrorCode(OK); + return aPipeDS; + +} + diff --git a/src/GEOMImpl/GEOMImpl_I3DPrimOperations.hxx b/src/GEOMImpl/GEOMImpl_I3DPrimOperations.hxx index 5773f2f47..d3d7ba49c 100644 --- a/src/GEOMImpl/GEOMImpl_I3DPrimOperations.hxx +++ b/src/GEOMImpl/GEOMImpl_I3DPrimOperations.hxx @@ -94,6 +94,10 @@ class GEOMImpl_I3DPrimOperations : public GEOM_IOperations { bool theWithContact, bool theWithCorrections); + Standard_EXPORT Handle(GEOM_Object) MakePipeShellsWithoutPath( + const Handle(TColStd_HSequenceOfTransient)& theBases, + const Handle(TColStd_HSequenceOfTransient)& theLocations); + }; #endif diff --git a/src/GEOMImpl/GEOMImpl_IMeasure.hxx b/src/GEOMImpl/GEOMImpl_IMeasure.hxx index 80915550b..db615f1f3 100644 --- a/src/GEOMImpl/GEOMImpl_IMeasure.hxx +++ b/src/GEOMImpl/GEOMImpl_IMeasure.hxx @@ -22,10 +22,15 @@ #include "GEOM_Function.hxx" -#define MEASURE_ARG_BASE 1 +//#define MEASURE_ARG_BASE 1 +//#define MEASURE_ARG_POINT 2 class GEOMImpl_IMeasure { + enum { + MEASURE_ARG_BASE = 1, + MEASURE_ARG_POINT = 2 + }; public: GEOMImpl_IMeasure(Handle(GEOM_Function) theFunction): _func(theFunction) {} @@ -35,6 +40,11 @@ class GEOMImpl_IMeasure Handle(GEOM_Function) GetBase() { return _func->GetReference(MEASURE_ARG_BASE); } + void SetPoint(Handle(GEOM_Function) thePnt) + { _func->SetReference(MEASURE_ARG_POINT, thePnt); } + + Handle(GEOM_Function) GetPoint() { return _func->GetReference(MEASURE_ARG_POINT); } + private: Handle(GEOM_Function) _func; diff --git a/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx b/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx index 5925ea6d4..67e26c014 100644 --- a/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx @@ -878,6 +878,70 @@ Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetCentreOfMass return aCDG; } +//============================================================================= +/*! + * GetNormal + */ +//============================================================================= +Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetNormal + (Handle(GEOM_Object) theFace, + Handle(GEOM_Object) theOptionalPoint) +{ + SetErrorCode(KO); + + if (theFace.IsNull()) return NULL; + + //Add a new Normale object + Handle(GEOM_Object) aNorm = GetEngine()->AddObject(GetDocID(), GEOM_VECTOR); + + //Add a new Normale function + Handle(GEOM_Function) aFunction = + aNorm->AddFunction(GEOMImpl_MeasureDriver::GetID(), VECTOR_FACE_NORMALE); + if (aFunction.IsNull()) return NULL; + + //Check if the function is set correctly + if (aFunction->GetDriverGUID() != GEOMImpl_MeasureDriver::GetID()) return NULL; + + GEOMImpl_IMeasure aCI (aFunction); + + Handle(GEOM_Function) aFace = theFace->GetLastFunction(); + if (aFace.IsNull()) return NULL; + + aCI.SetBase(aFace); + + if (!theOptionalPoint.IsNull()) { + Handle(GEOM_Function) anOptPnt = theOptionalPoint->GetLastFunction(); + aCI.SetPoint(anOptPnt); + } + + //Compute the Normale value + try { +#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 + OCC_CATCH_SIGNALS; +#endif + if (!GetSolver()->ComputeFunction(aFunction)) { + SetErrorCode("Measure driver failed to compute normake of face"); + return NULL; + } + } + catch (Standard_Failure) { + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + SetErrorCode(aFail->GetMessageString()); + return NULL; + } + + //Make a Python command + GEOM::TPythonDump pd (aFunction); + pd << aNorm << " = geompy.GetNormal(" << theFace; + if (!theOptionalPoint.IsNull()) { + pd << ", " << theOptionalPoint; + } + pd << ")"; + + SetErrorCode(OK); + return aNorm; +} + //============================================================================= /*! * GetBasicProperties diff --git a/src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx b/src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx index 2c221f3f3..24f6e5253 100644 --- a/src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx +++ b/src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx @@ -90,6 +90,9 @@ class GEOMImpl_IMeasureOperations : public GEOM_IOperations { Standard_EXPORT Handle(GEOM_Object) GetCentreOfMass (Handle(GEOM_Object) theShape); + Standard_EXPORT Handle(GEOM_Object) GetNormal (Handle(GEOM_Object) theFace, + Handle(GEOM_Object) theOptionalPoint); + Standard_EXPORT void GetBasicProperties (Handle(GEOM_Object) theShape, Standard_Real& theLength, Standard_Real& theSurfArea, diff --git a/src/GEOMImpl/GEOMImpl_MeasureDriver.cxx b/src/GEOMImpl/GEOMImpl_MeasureDriver.cxx index 52fdd93ce..69ffeabd8 100644 --- a/src/GEOMImpl/GEOMImpl_MeasureDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_MeasureDriver.cxx @@ -29,12 +29,20 @@ #include #include #include +#include #include #include #include #include +#include +#include + +#include +#include +#include +#include #include #include @@ -73,7 +81,8 @@ Standard_Integer GEOMImpl_MeasureDriver::Execute(TFunction_Logbook& log) const TopoDS_Shape aShape; - if (aType == CDG_MEASURE) { + if (aType == CDG_MEASURE) + { Handle(GEOM_Function) aRefBase = aCI.GetBase(); TopoDS_Shape aShapeBase = aRefBase->GetValue(); if (aShapeBase.IsNull()) { @@ -97,8 +106,99 @@ Standard_Integer GEOMImpl_MeasureDriver::Execute(TFunction_Logbook& log) const } aShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape(); + } + else if (aType == VECTOR_FACE_NORMALE) + { + // Face + Handle(GEOM_Function) aRefBase = aCI.GetBase(); + TopoDS_Shape aShapeBase = aRefBase->GetValue(); + if (aShapeBase.IsNull()) { + Standard_NullObject::Raise("Face for normale calculation is null"); + } + if (aShapeBase.ShapeType() != TopAbs_FACE) { + Standard_NullObject::Raise("Shape for normale calculation is not a face"); + } + TopoDS_Face aFace = TopoDS::Face(aShapeBase); + + // Point + gp_Pnt p1 (0,0,0); + + Handle(GEOM_Function) aPntFunc = aCI.GetPoint(); + if (!aPntFunc.IsNull()) + { + TopoDS_Shape anOptPnt = aPntFunc->GetValue(); + if (anOptPnt.IsNull()) + Standard_NullObject::Raise("Invalid shape given for point argument"); + p1 = BRep_Tool::Pnt(TopoDS::Vertex(anOptPnt)); + } + else + { + gp_Ax3 aPos = GEOMImpl_IMeasureOperations::GetPosition(aFace); + p1 = aPos.Location(); + } - } else { + // Point parameters on surface + Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace); + Handle(ShapeAnalysis_Surface) aSurfAna = new ShapeAnalysis_Surface (aSurf); + gp_Pnt2d pUV = aSurfAna->ValueOfUV(p1, Precision::Confusion()); + + // Normal direction + gp_Vec Vec1,Vec2; + BRepAdaptor_Surface SF (aFace); + SF.D1(pUV.X(), pUV.Y(), p1, Vec1, Vec2); + gp_Vec V = Vec1.Crossed(Vec2); + Standard_Real mod = V.Magnitude(); + if (mod < Precision::Confusion()) + Standard_NullObject::Raise("Normal vector of a face has null magnitude"); + + // Set length of normal vector to average radius of curvature + Standard_Real radius = 0.0; + GeomLProp_SLProps aProperties (aSurf, pUV.X(), pUV.Y(), 2, Precision::Confusion()); + if (aProperties.IsCurvatureDefined()) { + Standard_Real radius1 = Abs(aProperties.MinCurvature()); + Standard_Real radius2 = Abs(aProperties.MaxCurvature()); + if (Abs(radius1) > Precision::Confusion()) { + radius = 1.0 / radius1; + if (Abs(radius2) > Precision::Confusion()) { + radius = (radius + 1.0 / radius2) / 2.0; + } + } + else { + if (Abs(radius2) > Precision::Confusion()) { + radius = 1.0 / radius2; + } + } + } + + // Set length of normal vector to average dimension of the face + // (only if average radius of curvature is not appropriate) + if (radius < Precision::Confusion()) { + Bnd_Box B; + Standard_Real Xmin, Xmax, Ymin, Ymax, Zmin, Zmax; + BRepBndLib::Add(aFace, B); + B.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax); + radius = ((Xmax - Xmin) + (Ymax - Ymin) + (Zmax - Zmin)) / 3.0; + } + + if (radius < Precision::Confusion()) + radius = 1.0; + + V *= radius / mod; + + // consider the face orientation + if (aFace.Orientation() == TopAbs_REVERSED || + aFace.Orientation() == TopAbs_INTERNAL) { + V = - V; + } + + // Edge + gp_Pnt p2 = p1.Translated(V); + BRepBuilderAPI_MakeEdge aBuilder (p1, p2); + if (!aBuilder.IsDone()) + Standard_NullObject::Raise("Vector construction failed"); + aShape = aBuilder.Shape(); + } + else { } if (aShape.IsNull()) return 0; @@ -107,7 +207,7 @@ Standard_Integer GEOMImpl_MeasureDriver::Execute(TFunction_Logbook& log) const log.SetTouched(Label()); - return 1; + return 1; } diff --git a/src/GEOMImpl/GEOMImpl_PipeDriver.cxx b/src/GEOMImpl/GEOMImpl_PipeDriver.cxx index 320debb03..7bca5db26 100644 --- a/src/GEOMImpl/GEOMImpl_PipeDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_PipeDriver.cxx @@ -31,6 +31,8 @@ #include #include +#include +#include #include #include @@ -41,6 +43,7 @@ #include #include #include +#include #include #include @@ -59,9 +62,22 @@ #include #include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include #include #include @@ -72,6 +88,8 @@ #include "utilities.h" //#include "BRepTools.hxx" +//#include "GeomTools.hxx" +#include //======================================================================= @@ -108,6 +126,12 @@ static bool FillForOtherEdges(const TopoDS_Shape& F1, // creating map of vertex edges for both faces TopTools_IndexedDataMapOfShapeListOfShape aMapVertEdge1; TopExp::MapShapesAndAncestors(F1, TopAbs_VERTEX, TopAbs_EDGE, aMapVertEdge1); + if(!FF.Contains(F1)) + cout<<" FillForOtherEdges: map FF not contains key F1"< tol ) { - if(aCI) delete aCI; - Standard_ConstructionError::Raise - ("First location shapes is not coincided with first vertex of aWirePath"); - } - VLocs.ChangeValue(1) = VF; - edge = TopoDS::Edge(Edges.Last()); - tol = BRep_Tool::Tolerance(edge); - TopoDS_Vertex VL = sae.LastVertex(edge); - gp_Pnt PL = BRep_Tool::Pnt(VL); - if( PL.Distance(PLocs.Last()) > tol ) { - if(aCI) delete aCI; - Standard_ConstructionError::Raise - ("Last location shapes is not coincided with last vertex of aWirePath"); - } - VLocs.ChangeValue(nbLocs) = VL; - int jcurr = 2; - TopTools_SequenceOfShape tmpEdges; - for(i=1; i<=Edges.Length() && jcurr0 && Num2>0 ) { TopoDS_Wire W; B.MakeWire(W); - for(j=1; j<=tmpEdges.Length(); j++) - B.Add(W,tmpEdges.Value(j)); - B.Add(W,E); + for(i=Num1; i<=Num2; i++) { + B.Add(W,Edges.Value(i)); + } Wires.Append(W); - VLocs.ChangeValue(jcurr) = V2; - jcurr++; - tmpEdges.Clear(); } else { - // find distance between E and aLocs(jcurr) - double fp,lp; - Handle(Geom_Curve) C = BRep_Tool::Curve(E,fp,lp); - GeomAPI_ProjectPointOnCurve PPC (PLocs.Value(jcurr),C); - if( PPC.NbPoints()>0 && - PLocs.Value(jcurr).Distance(PPC.Point(1)) < tol ) { - double param = PPC.Parameter(1); - gp_Pnt PC1; - C->D0(param,PC1); - // split current edge - Handle(Geom_TrimmedCurve) tc1 = new Geom_TrimmedCurve(C,fp,param); - Handle(Geom_TrimmedCurve) tc2 = new Geom_TrimmedCurve(C,param,lp); - TopoDS_Edge E1,E2; - gp_Pnt Pfp; - C->D0(fp,Pfp); - if(Pfp.Distance(P1) tol ) { + if(aCI) delete aCI; + Standard_ConstructionError::Raise + ("First location shapes is not coincided with first vertex of aWirePath"); + } + VLocs.ChangeValue(1) = VF; + edge = TopoDS::Edge(Edges.Last()); + tol = BRep_Tool::Tolerance(edge); + TopoDS_Vertex VL = sae.LastVertex(edge); + gp_Pnt PL = BRep_Tool::Pnt(VL); + if( PL.Distance(PLocs.Last()) > tol ) { + if(aCI) delete aCI; + Standard_ConstructionError::Raise + ("Last location shapes is not coincided with last vertex of aWirePath"); + } + VLocs.ChangeValue(nbLocs) = VL; + int jcurr = 2; + TopTools_SequenceOfShape tmpEdges; + for(i=1; i<=Edges.Length() && jcurr0 && + PLocs.Value(jcurr).Distance(PPC.Point(1)) < tol ) { + double param = PPC.Parameter(1); + gp_Pnt PC1; + C->D0(param,PC1); + // split current edge + Handle(Geom_TrimmedCurve) tc1 = new Geom_TrimmedCurve(C,fp,param); + Handle(Geom_TrimmedCurve) tc2 = new Geom_TrimmedCurve(C,param,lp); + TopoDS_Edge E1,E2; + gp_Pnt Pfp; + C->D0(fp,Pfp); + if(Pfp.Distance(P1)GetBases(); + // vertex for recognition + Handle(TColStd_HSequenceOfTransient) VObjs = aCIDS->GetLocations(); + + Standard_Integer nbBases = aBasesObjs->Length(), + nbv = (VObjs.IsNull() ? 0 :VObjs->Length()); + + if( nbv != nbBases ) { + if(aCI) delete aCI; + Standard_ConstructionError::Raise("Number of shapes for recognition is invalid"); + } + + + TopTools_SequenceOfShape SecVs,Bases; + for(i=1; i<=nbBases; i++) { + // vertex + Handle(Standard_Transient) anItem = VObjs->Value(i); + if(anItem.IsNull()) + continue; + Handle(GEOM_Function) aRef = Handle(GEOM_Function)::DownCast(anItem); + TopoDS_Shape V = aRef->GetValue(); + if(V.IsNull() || V.ShapeType() != TopAbs_VERTEX) + continue; + SecVs.Append(V); + // section + anItem = aBasesObjs->Value(i); + if(anItem.IsNull()) + continue; + aRef = Handle(GEOM_Function)::DownCast(anItem); + TopoDS_Shape aSh = aRef->GetValue(); + if(aSh.IsNull()) + continue; + Bases.Append(aSh); + } + nbv = SecVs.Length(); + nbBases = Bases.Length(); + if( nbv != nbBases ) { + if(aCI) delete aCI; + Standard_ConstructionError::Raise("One of shapes for recognition is not a vertex"); + } + + TopoDS_Compound aComp; + B.MakeCompound(aComp); + + for(i=1 ; iface (and subshapes) + TopTools_IndexedDataMapOfShapeShape FF; + //TopoDS_Shape FS1 = SecFs.Value(i), FS2 = SecFs.Value(i+1); + TopoDS_Shape FS1, FS2; + TopoDS_Vertex V1 = TopoDS::Vertex(SecVs(i)); + TopoDS_Vertex V2 = TopoDS::Vertex(SecVs(i+1)); + FindFirstPairFaces(aShBase1, aShBase2, V1, V2, FS1, FS2); + + FF.Add(FS1,FS2); + cout<<" first pair of corresponding faces is found"<edge for created pipe edges + TopTools_IndexedDataMapOfShapeShape VPE; + ShapeAnalysis_Edge sae; + //cout<<"FF.Extent()="<IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) { + Handle(Geom_RectangularTrimmedSurface) RTS = + Handle(Geom_RectangularTrimmedSurface)::DownCast(S1); + S1 = RTS->BasisSurface(); + } + Handle(Geom_Plane) Pln1 = + Handle(Geom_Plane)::DownCast(S1); + if( Pln1.IsNull() ) { + if(aCI) delete aCI; + Standard_ConstructionError::Raise("Surface from face is not plane"); + } + gp_Vec aDir1(Pln1->Axis().Direction()); + + Handle(Geom_Surface) S2 = BRep_Tool::Surface(TopoDS::Face(F2)); + if(S2->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) { + Handle(Geom_RectangularTrimmedSurface) RTS = + Handle(Geom_RectangularTrimmedSurface)::DownCast(S2); + S2 = RTS->BasisSurface(); + } + Handle(Geom_Plane) Pln2 = + Handle(Geom_Plane)::DownCast(S2); + if( Pln2.IsNull() ) { + if(aCI) delete aCI; + Standard_ConstructionError::Raise("Surface from face is not plane"); + } + gp_Vec aDir2(Pln2->Axis().Direction()); + + gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(SecVs(i))); + gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(SecVs(i+1))); + gp_Vec aDir(P1,P2); + if(fabs(aDir.Angle(aDir1))>PI/2.) + aDir1.Reverse(); + if(fabs(aDir.Angle(aDir2))>PI/2.) + aDir2.Reverse(); + + TopExp_Explorer anExpE(F1,TopAbs_EDGE); + TopTools_SequenceOfShape aNewFs; + //int nbee=0; + for(; anExpE.More(); anExpE.Next()) { + TopoDS_Edge E1 = TopoDS::Edge(anExpE.Current()); + //nbee++; + if(!FF.Contains(E1)) + cout<<"map FF not contains key E1"<SetValue(1,P2); + HAP->SetValue(2,P3); + GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7); + anInt.Load(aDir1,aDir2); + anInt.Perform(); + C2 = anInt.Curve(); + B.MakeEdge(E2,C2,1.e-7); + B.Add(E2,TopoDS::Vertex(V2.Oriented(TopAbs_FORWARD))); + B.Add(E2,TopoDS::Vertex(V3.Oriented(TopAbs_REVERSED))); + VPE.Add(V2,E2); + } + // make E4 + TopoDS_Edge E4; + Handle(Geom_BSplineCurve) C4; + if(VPE.Contains(V1)) { + E4 = TopoDS::Edge(VPE.FindFromKey(V1)); + double fp,lp; + C4 = Handle(Geom_BSplineCurve)::DownCast(BRep_Tool::Curve(E4,fp,lp)); + } + else { + Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2); + HAP->SetValue(1,P1); + HAP->SetValue(2,P4); + GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7); + anInt.Load(aDir1,aDir2); + anInt.Perform(); + C4 = anInt.Curve(); + B.MakeEdge(E4,anInt.Curve(),1.e-7); + B.Add(E4,TopoDS::Vertex(V1.Oriented(TopAbs_FORWARD))); + B.Add(E4,TopoDS::Vertex(V4.Oriented(TopAbs_REVERSED))); + VPE.Add(V1,E4); + } + + TopoDS_Wire W; + B.MakeWire(W); + B.Add(W,E1); + B.Add(W,E2); + B.Add(W,E3); + B.Add(W,E4.Reversed()); + //cout<<" wire for edge "<IsKind(STANDARD_TYPE(Geom_Conic)) ) { + // IsConicC1 = true; + // cout<<"C1 - Geom_Conic"<IsKind(STANDARD_TYPE(Geom_Line)) || C1->IsKind(STANDARD_TYPE(Geom_Conic)) ) { + C1 = new Geom_TrimmedCurve(C1,fp,lp); + } + //if(IsConicC1) { + // double tol = BRep_Tool::Tolerance(E1); + // GeomConvert_ApproxCurve ApxC1(C1,tol,GeomAbs_C1,10,5); + // C1 = ApxC1.Curve(); + //} + Handle(Geom_Curve) C3 = BRep_Tool::Curve(E3,fp,lp); + if( C3->IsKind(STANDARD_TYPE(Geom_Line)) || C3->IsKind(STANDARD_TYPE(Geom_Conic)) ) { + C3 = new Geom_TrimmedCurve(C3,fp,lp); + } + //filebuf fic; + //ostream os(&fic); + //os.precision(15); + Handle(Geom_BSplineCurve) CE1 = + GeomConvert::CurveToBSplineCurve(C1,Convert_RationalC1); + if(CE1->Degree()<3) + CE1->IncreaseDegree(3); + Handle(Geom_BSplineCurve) CE2 = + GeomConvert::CurveToBSplineCurve(C2,Convert_RationalC1); + if(CE2->Degree()<3) + CE2->IncreaseDegree(3); + Handle(Geom_BSplineCurve) CE3 = + GeomConvert::CurveToBSplineCurve(C3,Convert_RationalC1); + if(CE3->Degree()<3) + CE3->IncreaseDegree(3); + Handle(Geom_BSplineCurve) CE4 = + GeomConvert::CurveToBSplineCurve(C4,Convert_RationalC1); + if(CE4->Degree()<3) + CE4->IncreaseDegree(3); + //cout<<"CE1->Degree()="<Degree()<<" CE2->Degree()="<Degree() + // <<" CE3->Degree()="<Degree()<<" CE4->Degree()="<Degree()<D0(fp1,P1C1); + C1->D0(lp1,P2C1); + gp_Pnt P1C3,P2C3; + C3->D0(fp2,P1C3); + C3->D0(lp2,P2C3); + int n1,n2; + double fp,lp; + // get points from C1 + if(P1.Distance(P1C1)<1.e-6) { + fp = fp1; + lp = lp1; + } + else { + fp = lp1; + lp = fp1; + } + double step = (lp-fp)/(NbP-1); + Points.SetValue(1,1,P1); + double par = fp; + for(n1=2; n1D0(par,P); + Points.SetValue(1,n1,P); + } + Points.SetValue(1,NbP,P2); + // get points from C3 + if(P4.Distance(P1C3)<1.e-6) { + fp = fp2; + lp = lp2; + } + else { + fp = lp2; + lp = fp2; + } + step = (lp-fp)/(NbP-1); + Points.SetValue(NbP,1,P4); + par = fp; + for(n1=2; n1D0(par,P); + Points.SetValue(NbP,n1,P); + } + Points.SetValue(NbP,NbP,P3); + // create isolines and get points from them + for(n1=1; n1<=NbP; n1++) { + gp_Pnt PI1 = Points.Value(1,n1); + gp_Pnt PI2 = Points.Value(NbP,n1); + Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2); + HAP->SetValue(1,PI1); + HAP->SetValue(2,PI2); + GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7); + anInt.Load(aDir1,aDir2); + anInt.Perform(); + Handle(Geom_Curve) iso = anInt.Curve(); + fp = iso->FirstParameter(); + lp = iso->LastParameter(); + step = (lp-fp)/(NbP-1); + par = fp; + TopoDS_Compound VComp; + B.MakeCompound(VComp); + for(n2=2; n2D0(par,P); + Points.SetValue(n2,n1,P); + } + } + // create surface and face + //Handle(Geom_BezierSurface) BS = new Geom_BezierSurface(Points); + BS = new Geom_BezierSurface(Points); + } + + BRepBuilderAPI_MakeFace BB(BS,W); + TopoDS_Face NewF = BB.Face(); + Handle(ShapeFix_Face) sff = new ShapeFix_Face(NewF); + sff->Perform(); + sff->FixOrientation(); + TopoDS_Face FixedFace = sff->Face(); + aNewFs.Append(FixedFace); + VPE.Add(E1,FixedFace); + //cout<<" face for edge "<SetTolerance(Precision::Confusion()); + aSewing->SetFaceMode(Standard_True); + aSewing->SetFloatingEdgesMode(Standard_False); + aSewing->SetNonManifoldMode(Standard_False); + for ( anExp.Init( aShell, TopAbs_FACE ); anExp.More(); anExp.Next() ) { + aSewing->Add(anExp.Current()); + } + aSewing->Perform(); + cout<<" shell for face "<SewedShape(); + //BRepTools::Write(aSewShape,"/dn02/users_Linux/skl/work/Bugs/14857/sew.brep"); + if( aSewShape.ShapeType() == TopAbs_SHELL ) { + aShell = TopoDS::Shell(aSewShape); + GProp_GProps aSystem; + BRepGProp::VolumeProperties(aShell, aSystem); + if(aSystem.Mass()<0) { + //cout<<"aSewShape is reversed"<Perform(); + //TopoDS_Shell FixedShell = sfs->Shell(); + /* + GProp_GProps aSystem; + BRepGProp::VolumeProperties(FixedShell, aSystem); + if(aSystem.Mass()<0) { + //cout<<"aSewShape is reversed"<GetPath(); - TopoDS_Shape aShapePath = aRefPath->GetValue(); - + TopoDS_Wire aWirePath; + if(aType != PIPE_SHELLS_WITHOUT_PATH) { + // working with path + Handle(GEOM_Function) aRefPath = aCI->GetPath(); + TopoDS_Shape aShapePath = aRefPath->GetValue(); - if (aShapePath.IsNull()) { - cout<<"Driver : path is null"<(aCI); //BRepOffsetAPI_MakePipeShell aBuilder(aWirePath); @@ -1159,16 +1932,14 @@ Standard_Integer GEOMImpl_PipeDriver::Execute(TFunction_Logbook& log) const Standard_Integer i =1, nbBases = aBasesObjs->Length(), nbLocs = (aLocObjs.IsNull() ? 0 :aLocObjs->Length()); - if(nbLocs && nbLocs != nbBases) - { + if(nbLocs && nbLocs != nbBases) { if(aCI) delete aCI; Standard_ConstructionError::Raise("Number of sections is not equal to number of locations "); } TopTools_SequenceOfShape aSeqBases; TopTools_SequenceOfShape aSeqLocs; TopTools_SequenceOfShape aSeqFaces; - for( ; i <= nbBases; i++) - { + for( ; i <= nbBases; i++) { Handle(Standard_Transient) anItem = aBasesObjs->Value(i); if(anItem.IsNull()) continue; @@ -1204,8 +1975,7 @@ Standard_Integer GEOMImpl_PipeDriver::Execute(TFunction_Logbook& log) const aSeqFaces.Append(aShapeBase); aSeqBases.Append(aWire); } - else if(aTypeBase == TopAbs_FACE) - { + else if(aTypeBase == TopAbs_FACE) { NeedCreateSolid = Standard_True; //for case one path should be used other type function aSeqFaces.Append(aShapeBase); @@ -1219,14 +1989,12 @@ Standard_Integer GEOMImpl_PipeDriver::Execute(TFunction_Logbook& log) const else if(aTypeBase == TopAbs_WIRE || aTypeBase == TopAbs_VERTEX) { aSeqBases.Append(aShapeBase); } - else if(aTypeBase == TopAbs_EDGE) - { + else if(aTypeBase == TopAbs_EDGE) { TopoDS_Edge anEdge = TopoDS::Edge(aShapeBase); TopoDS_Shape aWireProf = BRepBuilderAPI_MakeWire(anEdge); aSeqBases.Append(aWireProf); } - if(nbLocs) - { + if(nbLocs) { Handle(Standard_Transient) anItemLoc = aLocObjs->Value(i); if(anItemLoc.IsNull()) continue; @@ -1241,6 +2009,7 @@ Standard_Integer GEOMImpl_PipeDriver::Execute(TFunction_Logbook& log) const nbLocs = aSeqLocs.Length(); // skl 02.05.2007 + TopTools_SequenceOfShape Edges; if(nbLocs>0) { // we have to check that each location shape is a vertex from // path and update aSeqLocs if it is needed (and possible) @@ -1249,7 +2018,7 @@ Standard_Integer GEOMImpl_PipeDriver::Execute(TFunction_Logbook& log) const TopoDS_Vertex V = TopoDS::Vertex(aSeqLocs.Value(i)); PLocs.Append(BRep_Tool::Pnt(V)); } - TopTools_SequenceOfShape Edges; + //TopTools_SequenceOfShape Edges; TopExp_Explorer anExp; for ( anExp.Init( aWirePath, TopAbs_EDGE ); anExp.More(); anExp.Next() ) { Edges.Append(anExp.Current()); @@ -1347,39 +2116,153 @@ Standard_Integer GEOMImpl_PipeDriver::Execute(TFunction_Logbook& log) const } } - BRepOffsetAPI_MakePipeShell aBuilder(aWirePath); + // check curvature of wire for condition that + // max summary angle between directions along + // wire path must be < 4*PI. If not - split wire + // and seguences of shapes, perform pipe for each + // and make sewing after that + double fp,lp; + Handle(Geom_Curve) C = BRep_Tool::Curve(TopoDS::Edge(Edges.Value(1)),fp,lp); + gp_Pnt P1,P2; + gp_Vec Vec1,Vec2; + C->D1(fp,P1,Vec1); + C->D1(lp,P2,Vec2); + double SumAng = fabs(Vec1.Angle(Vec2)); + Vec1 = Vec2; + P1 = P2; + TColStd_SequenceOfInteger SplitEdgeNums,SplitLocNums; + int LastLoc = 1; + //cout<<"Edges.Length()="<D1(lp,P2,Vec2); + double ang = fabs(Vec1.Angle(Vec2)); + SumAng += ang; + if(SumAng>4*PI) { + SumAng = ang; + SplitEdgeNums.Append(i-1); + int j; + for(j=LastLoc+1; j<=aSeqLocs.Length(); j++) { + TopoDS_Vertex aVert = TopoDS::Vertex(aSeqLocs.Value(j)); + gp_Pnt P = BRep_Tool::Pnt(aVert); + if( P1.Distance(P) < tol ) { + SplitLocNums.Append(j); + LastLoc = j; + break; + } + } + } + Vec1 = Vec2; + P1 = P2; + } - Standard_Integer nbShapes = aSeqBases.Length(); - Standard_Integer step = nbShapes/nbBases; - - if(nbShapes < nbBases || fmod((double)nbShapes, (double)nbBases)) - { - if(aCI) delete aCI; - Standard_ConstructionError::Raise("Invalid sections were specified for building pipe"); + //cout<<"SplitEdgeNums.Length()="<SetTolerance(Precision::Confusion()); + aSewing->SetFaceMode(Standard_True); + aSewing->SetFloatingEdgesMode(Standard_False); + aSewing->SetNonManifoldMode(Standard_False); + for(i=1; i<=aSeqRes.Length(); i++) { + aSewing->Add(aSeqRes.Value(i)); + } + aSewing->Perform(); + aShape = aSewing->SewedShape(); } - - Standard_Integer ind =0; - for( i=1; i <= nbShapes && ind < nbShapes; i++) //i+nbBases <= nbShapes - { - TopTools_SequenceOfShape usedBases; - Standard_Integer j = 1; - for( ; j <= nbBases ; j++) - { - ind = i + (j-1)*step; - - TopoDS_Shape aWireProf = aSeqBases.Value(ind); - usedBases.Append(aWireProf); - if(nbLocs) - { - TopoDS_Shape aShapeLoc = aSeqLocs.Value(j); - TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc); - aBuilder.Add(aWireProf,aVert,aWithContact,aWithCorrect); - } - else - aBuilder.Add(aWireProf,aWithContact,aWithCorrect); + else { + // old implementation without splitting + BRepOffsetAPI_MakePipeShell aBuilder(aWirePath); + + Standard_Integer nbShapes = aSeqBases.Length(); + Standard_Integer step = nbShapes/nbBases; + + if(nbShapes < nbBases || fmod((double)nbShapes, (double)nbBases)) { + if(aCI) delete aCI; + Standard_ConstructionError::Raise("Invalid sections were specified for building pipe"); } - if(!aBuilder.IsReady()) - { + Standard_Integer ind =0; + for( i=1; i <= nbShapes && ind < nbShapes; i++) { //i+nbBases <= nbShapes + TopTools_SequenceOfShape usedBases; + Standard_Integer j = 1; + for( ; j <= nbBases ; j++) { + ind = i + (j-1)*step; + TopoDS_Shape aWireProf = aSeqBases.Value(ind); + usedBases.Append(aWireProf); + if(nbLocs) { + TopoDS_Shape aShapeLoc = aSeqLocs.Value(j); + TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc); + aBuilder.Add(aWireProf,aVert,aWithContact,aWithCorrect); + } + else + aBuilder.Add(aWireProf,aWithContact,aWithCorrect); + } + if(!aBuilder.IsReady()) { if(aCI) delete aCI; Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid"); } @@ -1388,17 +2271,17 @@ Standard_Integer GEOMImpl_PipeDriver::Execute(TFunction_Logbook& log) const aSeqFaces.Append(aShape); for( j = 1; j <=usedBases.Length(); j++) aBuilder.Delete(usedBases.Value(j)); - } + } - //for case if section is face - if(aSeqFaces.Length() >1) - { - BRep_Builder aB; - TopoDS_Compound aComp; - aB.MakeCompound(aComp); - for( i = 1; i <= aSeqFaces.Length(); i++) - aB.Add(aComp,aSeqFaces.Value(i)); - aShape = aComp; + //for case if section is face + if(aSeqFaces.Length() >1) { + BRep_Builder aB; + TopoDS_Compound aComp; + aB.MakeCompound(aComp); + for( i = 1; i <= aSeqFaces.Length(); i++) + aB.Add(aComp,aSeqFaces.Value(i)); + aShape = aComp; + } } } @@ -1407,6 +2290,11 @@ Standard_Integer GEOMImpl_PipeDriver::Execute(TFunction_Logbook& log) const aShape = CreatePipeForShellSections(aWirePath,aCI); } + //building pipe shell sections without path + else if (aType == PIPE_SHELLS_WITHOUT_PATH) { + aShape = CreatePipeShellsWithoutPath(aCI); + } + if (aShape.IsNull()) return 0; BRepCheck_Analyzer ana (aShape, Standard_False); diff --git a/src/GEOMImpl/GEOMImpl_Types.hxx b/src/GEOMImpl/GEOMImpl_Types.hxx index 23b93efd5..c33d81b14 100755 --- a/src/GEOMImpl/GEOMImpl_Types.hxx +++ b/src/GEOMImpl/GEOMImpl_Types.hxx @@ -97,6 +97,7 @@ #define VECTOR_TWO_PNT 1 #define VECTOR_DX_DY_DZ 2 #define VECTOR_TANGENT_CURVE_PAR 3 +#define VECTOR_FACE_NORMALE 4 #define PLANE_PNT_VEC 1 #define PLANE_FACE 2 diff --git a/src/GEOM_I/GEOM_I3DPrimOperations_i.cc b/src/GEOM_I/GEOM_I3DPrimOperations_i.cc index 83a98e3a4..e730e0e03 100644 --- a/src/GEOM_I/GEOM_I3DPrimOperations_i.cc +++ b/src/GEOM_I/GEOM_I3DPrimOperations_i.cc @@ -597,7 +597,7 @@ GEOM::GEOM_Object_ptr GEOM_I3DPrimOperations_i::MakePipeWithShellSections CORBA::Boolean theWithContact, CORBA::Boolean theWithCorrections) { - GEOM::GEOM_Object_var aGEOMObject; + GEOM::GEOM_Object_var aGEOMObject; //Set a not done flag GetOperations()->SetNotDone(); @@ -659,3 +659,57 @@ GEOM::GEOM_Object_ptr GEOM_I3DPrimOperations_i::MakePipeWithShellSections return GetObject(anObject); } + + +//============================================================================= +/*! + * MakePipeShellsWithoutPath + */ +//============================================================================= +GEOM::GEOM_Object_ptr GEOM_I3DPrimOperations_i::MakePipeShellsWithoutPath + (const GEOM::ListOfGO& theBases, + const GEOM::ListOfGO& theLocations) +{ + GEOM::GEOM_Object_var aGEOMObject; + + //Set a not done flag + GetOperations()->SetNotDone(); + Handle(TColStd_HSequenceOfTransient) aSeqBases = new TColStd_HSequenceOfTransient; + Handle(TColStd_HSequenceOfTransient) aSeqLocations = new TColStd_HSequenceOfTransient; + int ind=0, aNbBases=0, aNbLocs=0; + + //Get the shapes + aNbBases = theBases.length(); + aNbLocs = theLocations.length(); + + if( aNbLocs && aNbBases != aNbLocs) + return aGEOMObject._retn(); + + for (ind = 0; ind < aNbBases; ind++) { + if (theBases[ind] == NULL) continue; + Handle(GEOM_Object) aBase = GetOperations()->GetEngine()-> + GetObject(theBases[ind]->GetStudyID(), theBases[ind]->GetEntry()); + if(aBase.IsNull()) + continue; + if(aNbLocs) { + Handle(GEOM_Object) aLoc = GetOperations()->GetEngine()->GetObject + (theLocations[ind]->GetStudyID(), theLocations[ind]->GetEntry()); + if(aLoc.IsNull()) + continue; + aSeqLocations->Append(aLoc); + } + aSeqBases->Append(aBase); + } + + if(!aSeqBases->Length()) + return aGEOMObject._retn(); + + // Make pipe + Handle(GEOM_Object) anObject = + GetOperations()->MakePipeShellsWithoutPath(aSeqBases,aSeqLocations); + + if (!GetOperations()->IsDone() || anObject.IsNull()) + return aGEOMObject._retn(); + + return GetObject(anObject); +} diff --git a/src/GEOM_I/GEOM_I3DPrimOperations_i.hh b/src/GEOM_I/GEOM_I3DPrimOperations_i.hh index fe86685a9..6c3febbc9 100644 --- a/src/GEOM_I/GEOM_I3DPrimOperations_i.hh +++ b/src/GEOM_I/GEOM_I3DPrimOperations_i.hh @@ -113,6 +113,9 @@ class GEOM_I_EXPORT GEOM_I3DPrimOperations_i : CORBA::Boolean theWithContact, CORBA::Boolean theWithCorrections); + GEOM::GEOM_Object_ptr MakePipeShellsWithoutPath(const GEOM::ListOfGO& theBases, + const GEOM::ListOfGO& theLocations); + ::GEOMImpl_I3DPrimOperations* GetOperations() { return (::GEOMImpl_I3DPrimOperations*)GetImpl(); } }; diff --git a/src/GEOM_I/GEOM_IMeasureOperations_i.cc b/src/GEOM_I/GEOM_IMeasureOperations_i.cc index 7be304056..d4e8c6a8e 100644 --- a/src/GEOM_I/GEOM_IMeasureOperations_i.cc +++ b/src/GEOM_I/GEOM_IMeasureOperations_i.cc @@ -141,7 +141,7 @@ GEOM::GEOM_Object_ptr GEOM_IMeasureOperations_i::GetCentreOfMass //Set a not done flag GetOperations()->SetNotDone(); - if (theShape == NULL) return aGEOMObject._retn(); + if (CORBA::is_nil(theShape)) return aGEOMObject._retn(); //Get the reference shape Handle(GEOM_Object) aShape = GetOperations()->GetEngine()->GetObject @@ -157,6 +157,41 @@ GEOM::GEOM_Object_ptr GEOM_IMeasureOperations_i::GetCentreOfMass return GetObject(anObject); } +//============================================================================= +/*! + * GetNormal + */ +//============================================================================= +GEOM::GEOM_Object_ptr GEOM_IMeasureOperations_i::GetNormal + (GEOM::GEOM_Object_ptr theFace, + GEOM::GEOM_Object_ptr theOptionalPoint) +{ + GEOM::GEOM_Object_var aGEOMObject; + + //Set a not done flag + GetOperations()->SetNotDone(); + + if (CORBA::is_nil(theFace)) return aGEOMObject._retn(); + + //Get the reference shape + Handle(GEOM_Object) aFace = GetOperations()->GetEngine()->GetObject + (theFace->GetStudyID(), theFace->GetEntry()); + + if (aFace.IsNull()) return aGEOMObject._retn(); + + // Make Vector - normal to theFace (in point theOptionalPoint if the face is not planar) + Handle(GEOM_Object) anOptionalPoint; + if (!CORBA::is_nil(theOptionalPoint)) { + anOptionalPoint = GetOperations()->GetEngine()->GetObject + (theOptionalPoint->GetStudyID(), theOptionalPoint->GetEntry()); + } + Handle(GEOM_Object) anObject = GetOperations()->GetNormal(aFace, anOptionalPoint); + if (!GetOperations()->IsDone() || anObject.IsNull()) + return aGEOMObject._retn(); + + return GetObject(anObject); +} + //============================================================================= /*! * GetBasicProperties diff --git a/src/GEOM_I/GEOM_IMeasureOperations_i.hh b/src/GEOM_I/GEOM_IMeasureOperations_i.hh index 218a0bd76..4db8a26d4 100644 --- a/src/GEOM_I/GEOM_IMeasureOperations_i.hh +++ b/src/GEOM_I/GEOM_IMeasureOperations_i.hh @@ -56,6 +56,9 @@ class GEOM_I_EXPORT GEOM_IMeasureOperations_i : GEOM::GEOM_Object_ptr GetCentreOfMass (GEOM::GEOM_Object_ptr theShape); + GEOM::GEOM_Object_ptr GetNormal (GEOM::GEOM_Object_ptr theFace, + GEOM::GEOM_Object_ptr theOptionalPoint); + void GetInertia (GEOM::GEOM_Object_ptr theShape, CORBA::Double& I11, CORBA::Double& I12, CORBA::Double& I13, CORBA::Double& I21, CORBA::Double& I22, CORBA::Double& I23, diff --git a/src/GEOM_I_Superv/GEOM_Superv_i.cc b/src/GEOM_I_Superv/GEOM_Superv_i.cc index 31c215150..5694df6da 100644 --- a/src/GEOM_I_Superv/GEOM_Superv_i.cc +++ b/src/GEOM_I_Superv/GEOM_Superv_i.cc @@ -993,6 +993,7 @@ GEOM::GEOM_Object_ptr GEOM_Superv_i::MakePipeWithDifferentSections return anObj; } + //============================================================================= // MakePipe: //============================================================================= @@ -1015,6 +1016,24 @@ GEOM::GEOM_Object_ptr GEOM_Superv_i::MakePipeWithShellSections return anObj; } + +//============================================================================= +// MakePipe: +//============================================================================= +GEOM::GEOM_Object_ptr GEOM_Superv_i::MakePipeShellsWithoutPath + (const GEOM::ListOfGO& theBases, + const GEOM::ListOfGO& theLocations) +{ + beginService( " GEOM_Superv_i::MakePipeShellsWithoutPath" ); + MESSAGE("GEOM_Superv_i::MakePipeShellsWithoutPath"); + get3DPrimOp(); + GEOM::GEOM_Object_ptr anObj = + my3DPrimOp->MakePipeShellsWithoutPath(theBases,theLocations); + endService( " GEOM_Superv_i::MakePipeShellsWithoutPath" ); + return anObj; +} + + //============================================================================= // MakeFuse: //============================================================================= diff --git a/src/GEOM_I_Superv/GEOM_Superv_i.hh b/src/GEOM_I_Superv/GEOM_Superv_i.hh index 6075d2405..da8451222 100644 --- a/src/GEOM_I_Superv/GEOM_Superv_i.hh +++ b/src/GEOM_I_Superv/GEOM_Superv_i.hh @@ -244,6 +244,9 @@ public: CORBA::Boolean theWithContact, CORBA::Boolean theWithCorrections); + GEOM::GEOM_Object_ptr MakePipeShellsWithoutPath(const GEOM::ListOfGO& theBases, + const GEOM::ListOfGO& theLocations); + //-----------------------------------------------------------// // BooleanOperations // //-----------------------------------------------------------// diff --git a/src/GEOM_SWIG/GEOM_TestMeasures.py b/src/GEOM_SWIG/GEOM_TestMeasures.py index 1ca3cbccd..d552abf06 100644 --- a/src/GEOM_SWIG/GEOM_TestMeasures.py +++ b/src/GEOM_SWIG/GEOM_TestMeasures.py @@ -109,6 +109,22 @@ def TestMeasureOperations (geompy, math): if Coords[0] != 5 or Coords[1] != 15 or Coords[2] != 35: print "But must be (5, 15, 35)" + ####### GetNormal ####### + + faces = geompy.SubShapeAllSorted(box, geompy.ShapeType["FACE"]) + face0 = faces[0] + vnorm = geompy.GetNormal(face0) + if vnorm is None: + raise RuntimeError, "GetNormal(face0) failed" + else: + geompy.addToStudy(face0, "Face0") + geompy.addToStudy(vnorm, "Normale to Face0") + print "\nNormale of face has been successfully obtained:" + #Coords = geompy.PointCoordinates(pcdg) + #print "(", Coords[0], ", ", Coords[1], ", ", Coords[2], ")" + #if Coords[0] != 5 or Coords[1] != 15 or Coords[2] != 35: + # print "But must be (5, 15, 35)" + ####### MinDistance ####### MinDist = geompy.MinDistance(box, cube) diff --git a/src/GEOM_SWIG/geompyDC.py b/src/GEOM_SWIG/geompyDC.py index 011711d17..ae478628e 100644 --- a/src/GEOM_SWIG/geompyDC.py +++ b/src/GEOM_SWIG/geompyDC.py @@ -731,9 +731,12 @@ class geompyDC(GEOM._objref_GEOM_Gen): # orthogonal to the spine tangent in the correspondent point # @return New GEOM_Object, containing the created pipe. # - # Example: see GEOM_TestAll.py - def MakePipeWithDifferentSections(self,theSeqBases, theLocations,thePath,theWithContact,theWithCorrection): - anObj = self.PrimOp.MakePipeWithDifferentSections(theSeqBases, theLocations,thePath,theWithContact,theWithCorrection) + def MakePipeWithDifferentSections(self, theSeqBases, + theLocations, thePath, + theWithContact, theWithCorrection): + anObj = self.PrimOp.MakePipeWithDifferentSections(theSeqBases, + theLocations, thePath, + theWithContact, theWithCorrection) if self.PrimOp.IsDone() == 0: print "MakePipeWithDifferentSections : ", self.PrimOp.GetErrorCode() return anObj @@ -755,7 +758,6 @@ class geompyDC(GEOM._objref_GEOM_Gen): # orthogonal to the spine tangent in the correspondent point # @return New GEOM_Object, containing the created solids. # - # Example: see GEOM_TestAll.py def MakePipeWithShellSections(self,theSeqBases, theSeqSubBases, theLocations, thePath, theWithContact, theWithCorrection): @@ -765,7 +767,50 @@ class geompyDC(GEOM._objref_GEOM_Gen): if self.PrimOp.IsDone() == 0: print "MakePipeWithShellSections : ", self.PrimOp.GetErrorCode() return anObj - + + def MakePipeWithShellSectionsBySteps(self, theSeqBases, theSeqSubBases, + theLocations, thePath, + theWithContact, theWithCorrection): + res = [] + nbsect = len(theSeqBases) + nbsubsect = len(theSeqSubBases) + #print "nbsect = ",nbsect + for i in range(1,nbsect): + #print " i = ",i + tmpSeqBases = [ theSeqBases[i-1], theSeqBases[i] ] + tmpLocations = [ theLocations[i-1], theLocations[i] ] + tmpSeqSubBases = [] + if nbsubsect>0: tmpSeqSubBases = [ theSeqSubBases[i-1], theSeqSubBases[i] ] + anObj = self.PrimOp.MakePipeWithShellSections(tmpSeqBases, tmpSeqSubBases, + tmpLocations, thePath, + theWithContact, theWithCorrection) + if self.PrimOp.IsDone() == 0: + print "Problems with pipe creation between ",i," and ",i+1," sections" + print "MakePipeWithShellSections : ", self.PrimOp.GetErrorCode() + break + else: + print "Pipe between ",i," and ",i+1," sections is OK" + res.append(anObj) + pass + pass + + resc = self.MakeCompound(res) + #resc = self.MakeSewing(res, 0.001) + #print "resc: ",resc + return resc + + ## Create solids between given sections + # @param theSeqBases - list of sections (shell or face). + # @param theLocations - list of corresponding vertexes + # @return New GEOM_Object, containing the created solids. + # + def MakePipeShellsWithoutPath(self, theSeqBases, theLocations): + anObj = self.PrimOp.MakePipeShellsWithoutPath(theSeqBases, theLocations) + if self.PrimOp.IsDone() == 0: + print "MakePipeShellsWithoutPath : ", self.PrimOp.GetErrorCode() + return anObj + + # ----------------------------------------------------------------------------- # Create base shapes # ----------------------------------------------------------------------------- @@ -2099,6 +2144,19 @@ class geompyDC(GEOM._objref_GEOM_Gen): print "GetCentreOfMass : ", self.MeasuOp.GetErrorCode() return anObj + ## Get a normale to the given face. If the point is not given, + # the normale is calculated at the center of mass. + # @param theFace Face to define normale of. + # @param theOptionalPoint Point to compute the normale at. + # @return New GEOM_Object, containing the created vector. + # + # Example: see GEOM_TestMeasures.py + def GetNormal(self, theFace, theOptionalPoint = None): + anObj = self.MeasuOp.GetNormal(theFace, theOptionalPoint) + if self.MeasuOp.IsDone() == 0: + print "GetNormal : ", self.MeasuOp.GetErrorCode() + return anObj + ## Check a topology of the given shape. # @param theShape Shape to check validity of. # @param theIsCheckGeom If FALSE, only the shape's topology will be checked, diff --git a/src/MeasureGUI/Makefile.am b/src/MeasureGUI/Makefile.am index bdd6b86e5..e2462292f 100644 --- a/src/MeasureGUI/Makefile.am +++ b/src/MeasureGUI/Makefile.am @@ -47,6 +47,7 @@ dist_libMeasureGUI_la_SOURCES = \ MeasureGUI_Skeleton.cxx \ MeasureGUI_PropertiesDlg.cxx \ MeasureGUI_CenterMassDlg.cxx \ + MeasureGUI_NormaleDlg.cxx \ MeasureGUI_InertiaDlg.cxx \ MeasureGUI_BndBoxDlg.cxx \ MeasureGUI_DistanceDlg.cxx \ @@ -68,6 +69,7 @@ MOC_FILES = \ MeasureGUI_Skeleton_moc.cxx \ MeasureGUI_PropertiesDlg_moc.cxx \ MeasureGUI_CenterMassDlg_moc.cxx \ + MeasureGUI_NormaleDlg_moc.cxx \ MeasureGUI_InertiaDlg_moc.cxx \ MeasureGUI_BndBoxDlg_moc.cxx \ MeasureGUI_DistanceDlg_moc.cxx \ diff --git a/src/MeasureGUI/MeasureGUI.cxx b/src/MeasureGUI/MeasureGUI.cxx index ffd5a7e84..84571cf76 100644 --- a/src/MeasureGUI/MeasureGUI.cxx +++ b/src/MeasureGUI/MeasureGUI.cxx @@ -35,6 +35,7 @@ #include "MeasureGUI_PropertiesDlg.h" // Method PROPERTIES #include "MeasureGUI_CenterMassDlg.h" // Method CENTER MASS +#include "MeasureGUI_NormaleDlg.h" // Method NORMALE #include "MeasureGUI_InertiaDlg.h" // Method INERTIA #include "MeasureGUI_BndBoxDlg.h" // Method BNDBOX #include "MeasureGUI_DistanceDlg.h" // Method DISTANCE @@ -78,6 +79,7 @@ bool MeasureGUI::OnGUIEvent( int theCommandID, SUIT_Desktop* parent ) case 701 : new MeasureGUI_PropertiesDlg (getGeometryGUI(), parent); break; // LENGTH, AREA AND VOLUME case 702 : new MeasureGUI_CenterMassDlg (getGeometryGUI(), parent); break; // CENTER MASS case 703 : new MeasureGUI_InertiaDlg (getGeometryGUI(), parent); break; // INERTIA + case 704 : new MeasureGUI_NormaleDlg (getGeometryGUI(), parent); break; // NORMALE case 7041: new MeasureGUI_BndBoxDlg (getGeometryGUI(), parent); break; // BOUNDING BOX case 7042: new MeasureGUI_DistanceDlg (getGeometryGUI(), parent); break; // MIN DISTANCE case 7043: new MeasureGUI_AngleDlg (getGeometryGUI(), parent); break; // ANGLE diff --git a/src/MeasureGUI/MeasureGUI_NormaleDlg.cxx b/src/MeasureGUI/MeasureGUI_NormaleDlg.cxx new file mode 100644 index 000000000..32c6d9aff --- /dev/null +++ b/src/MeasureGUI/MeasureGUI_NormaleDlg.cxx @@ -0,0 +1,281 @@ +// GEOM GEOMGUI : GUI for Geometry component +// +// 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// +// +// File : MeasureGUI_NormaleDlg.cxx +// Author : Julia DOROVSKIKH +// Module : GEOM +// $Header$ + +#include "MeasureGUI_NormaleDlg.h" + +#include "SUIT_Session.h" +#include "SalomeApp_Application.h" +#include "LightApp_SelectionMgr.h" + +#include + +#include "GEOMImpl_Types.hxx" + +#include "utilities.h" + +//================================================================================= +// class : MeasureGUI_NormaleDlg() +// purpose : Constructs a MeasureGUI_NormaleDlg which is a child of 'parent', with the +// name 'name' and widget flags set to 'f'. +// The dialog will by default be modeless, unless you set 'modal' to +// TRUE to construct a modal dialog. +//================================================================================= +MeasureGUI_NormaleDlg::MeasureGUI_NormaleDlg (GeometryGUI* theGeometryGUI, QWidget* parent, + const char* name, bool modal, WFlags fl) + :GEOMBase_Skeleton(theGeometryGUI, parent, name, modal, WStyle_Customize | + WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu) +{ + SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr(); + QPixmap image0 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_NORMALE"))); + QPixmap image1 (aResMgr->loadPixmap("GEOM", tr("ICON_SELECT"))); + + setCaption(tr("GEOM_NORMALE_TITLE")); + + /***************************************************************/ + GroupConstructors->setTitle(tr("GEOM_NORMALE")); + RadioButton1->setPixmap(image0); + RadioButton2->close(TRUE); + RadioButton3->close(TRUE); + + GroupArgs = new DlgRef_2Sel_QTD (this, "GroupArgs"); + GroupArgs->GroupBox1->setTitle(tr("GEOM_ARGUMENTS")); + + GroupArgs->TextLabel1->setText(tr("GEOM_FACE")); + GroupArgs->TextLabel2->setText(tr("GEOM_POINT")); + + GroupArgs->PushButton1->setPixmap(image1); + GroupArgs->PushButton2->setPixmap(image1); + + Layout1->addWidget(GroupArgs, 2, 0); + /***************************************************************/ + + setHelpFileName("normale.htm"); + + Init(); +} + +//================================================================================= +// function : ~MeasureGUI_NormaleDlg() +// purpose : Destroys the object and frees any allocated resources +//================================================================================= +MeasureGUI_NormaleDlg::~MeasureGUI_NormaleDlg() +{ + // no need to delete child widgets, Qt does it all for us +} + +//================================================================================= +// function : Init() +// purpose : +//================================================================================= +void MeasureGUI_NormaleDlg::Init() +{ + /* init variables */ + GroupArgs->LineEdit1->setReadOnly(true); + GroupArgs->LineEdit2->setReadOnly(true); + + myFace = GEOM::GEOM_Object::_nil(); + myPoint = GEOM::GEOM_Object::_nil(); + + myEditCurrentArgument = GroupArgs->LineEdit1; + globalSelection(GEOM_FACE); + + /* signals and slots connections */ + connect(buttonOk, SIGNAL(clicked()), this, SLOT(ClickOnOk())); + connect(buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnApply())); + + connect(GroupArgs->PushButton1, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument())); + connect(GroupArgs->PushButton2, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument())); + + connect(GroupArgs->LineEdit1, SIGNAL(returnPressed()), this, SLOT(LineEditReturnPressed())); + connect(GroupArgs->LineEdit2, SIGNAL(returnPressed()), this, SLOT(LineEditReturnPressed())); + + connect(myGeomGUI->getApp()->selectionMgr(), + SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); + + initName(tr("GEOM_VECTOR_NORMALE")); + + //ConstructorsClicked(0); + SelectionIntoArgument(); + + /* displays Dialog */ + GroupArgs->show(); + this->show(); +} + +//================================================================================= +// function : ClickOnOk() +// purpose : +//================================================================================= +void MeasureGUI_NormaleDlg::ClickOnOk() +{ + if (ClickOnApply()) + ClickOnCancel(); +} + +//================================================================================= +// function : ClickOnApply() +// purpose : +//================================================================================= +bool MeasureGUI_NormaleDlg::ClickOnApply() +{ + if (!onAccept()) + return false; + + initName(); + return true; +} + +//================================================================================= +// function : SelectionIntoArgument() +// purpose : Called when selection as changed or other case +//================================================================================= +void MeasureGUI_NormaleDlg::SelectionIntoArgument() +{ + erasePreview(); + myEditCurrentArgument->setText(""); + + if (myEditCurrentArgument == GroupArgs->LineEdit1) { + myFace = GEOM::GEOM_Object::_nil(); + } + else if (myEditCurrentArgument == GroupArgs->LineEdit2) { + myPoint = GEOM::GEOM_Object::_nil(); + } + + if (IObjectCount() != 1) + return; + + // nbSel == 1 + Standard_Boolean testResult = Standard_False; + GEOM::GEOM_Object_var aSelectedObject = + GEOMBase::ConvertIOinGEOMObject(firstIObject(), testResult); + + if (!testResult) + return; + + if (myEditCurrentArgument == GroupArgs->LineEdit1) { + myFace = aSelectedObject; + } + else if (myEditCurrentArgument == GroupArgs->LineEdit2) { + myPoint = aSelectedObject; + } + + myEditCurrentArgument->setText(GEOMBase::GetName(aSelectedObject)); + + displayPreview(); +} + +//================================================================================= +// function : LineEditReturnPressed() +// purpose : +//================================================================================= +void MeasureGUI_NormaleDlg::LineEditReturnPressed() +{ + QLineEdit* send = (QLineEdit*)sender(); + if (send == GroupArgs->LineEdit1 || + send == GroupArgs->LineEdit2) + { + myEditCurrentArgument = send; + GEOMBase_Skeleton::LineEditReturnPressed(); + } +} + +//================================================================================= +// function : SetEditCurrentArgument() +// purpose : +//================================================================================= +void MeasureGUI_NormaleDlg::SetEditCurrentArgument() +{ + QPushButton* send = (QPushButton*)sender(); + + if (send == GroupArgs->PushButton1) { + myEditCurrentArgument = GroupArgs->LineEdit1; + globalSelection(GEOM_FACE); + } + else if (send == GroupArgs->PushButton2) { + myEditCurrentArgument = GroupArgs->LineEdit2; + globalSelection(GEOM_POINT); + } + + myEditCurrentArgument->setFocus(); + SelectionIntoArgument(); +} + +//================================================================================= +// function : ActivateThisDialog() +// purpose : +//================================================================================= +void MeasureGUI_NormaleDlg::ActivateThisDialog() +{ + GEOMBase_Skeleton::ActivateThisDialog(); + + SelectionIntoArgument(); +} + +//================================================================================= +// function : enterEvent() +// purpose : +//================================================================================= +void MeasureGUI_NormaleDlg::enterEvent (QEvent* e) +{ + if (!GroupConstructors->isEnabled()) + ActivateThisDialog(); +} + +//================================================================================= +// function : createOperation +// purpose : +//================================================================================= +GEOM::GEOM_IOperations_ptr MeasureGUI_NormaleDlg::createOperation() +{ + return getGeomEngine()->GetIMeasureOperations(getStudyId()); +} + +//================================================================================= +// function : isValid +// purpose : +//================================================================================= +bool MeasureGUI_NormaleDlg::isValid (QString&) +{ + //return !CORBA::is_nil(myFace) && !CORBA::is_nil(myPoint); + return !CORBA::is_nil(myFace); +} + +//================================================================================= +// function : execute +// purpose : +//================================================================================= +bool MeasureGUI_NormaleDlg::execute (ObjectList& objects) +{ + GEOM::GEOM_Object_var anObj = + GEOM::GEOM_IMeasureOperations::_narrow(getOperation())->GetNormal(myFace, myPoint); + + if (!anObj->_is_nil()) + objects.push_back(anObj._retn()); + + return true; +} diff --git a/src/MeasureGUI/MeasureGUI_NormaleDlg.h b/src/MeasureGUI/MeasureGUI_NormaleDlg.h new file mode 100644 index 000000000..757c755d9 --- /dev/null +++ b/src/MeasureGUI/MeasureGUI_NormaleDlg.h @@ -0,0 +1,74 @@ +// GEOM GEOMGUI : GUI for Geometry component +// +// 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// +// +// File : MeasureGUI_NormaleDlg.h +// Author : Julia DOROVSKIKH +// Module : GEOM + +#ifndef DIALOGBOX_NORMALE_H +#define DIALOGBOX_NORMALE_H + +#include "GEOM_MeasureGUI.hxx" + +#include "GEOMBase_Skeleton.h" +#include "DlgRef_2Sel_QTD.h" + +//================================================================================= +// class : MeasureGUI_NormaleDlg +// purpose : +//================================================================================= +class GEOM_MEASUREGUI_EXPORT MeasureGUI_NormaleDlg : public GEOMBase_Skeleton +{ + Q_OBJECT + +public: + MeasureGUI_NormaleDlg (GeometryGUI* theGeometryGUI, QWidget* parent = 0, + const char* name = 0, bool modal = FALSE, WFlags fl = 0); + ~MeasureGUI_NormaleDlg(); + +protected: + // redefined from GEOMBase_Helper + virtual GEOM::GEOM_IOperations_ptr createOperation(); + virtual bool isValid (QString& msg); + virtual bool execute (ObjectList& objects); + +private: + void Init(); + void enterEvent (QEvent* e); + + GEOM::GEOM_Object_var myFace; + GEOM::GEOM_Object_var myPoint; + + DlgRef_2Sel_QTD* GroupArgs; + +private slots: + void ClickOnOk(); + bool ClickOnApply(); + + void ActivateThisDialog(); + void LineEditReturnPressed(); + void SelectionIntoArgument(); + void SetEditCurrentArgument(); +}; + +#endif // DIALOGBOX_NORMALE_H -- 2.39.2