From 7c84bd2206985aa1920c58afa118601b24dd7a3a Mon Sep 17 00:00:00 2001 From: skv Date: Wed, 24 Sep 2014 18:13:01 +0400 Subject: [PATCH] Create CAF representation; create shape --- src/GEOM/GEOM_Function.cxx | 70 ++++++++ src/GEOM/GEOM_Function.hxx | 13 ++ src/GEOMImpl/CMakeLists.txt | 2 + src/GEOMImpl/GEOMImpl_ICurvesOperations.cxx | 102 ++++++++++- src/GEOMImpl/GEOMImpl_IPolyline2D.cxx | 125 +++++++++++++ src/GEOMImpl/GEOMImpl_IPolyline2D.hxx | 95 ++++++++++ src/GEOMImpl/GEOMImpl_PolylineDriver.cxx | 130 +++++++++++++- src/GEOMImpl/GEOMImpl_PolylineDriver.hxx | 3 + src/GEOMImpl/GEOMImpl_Types.hxx | 5 + src/GEOM_SWIG/gsketcher.py | 7 +- src/SKETCHER/CMakeLists.txt | 3 + src/SKETCHER/Sketcher.hxx | 39 ++++ src/SKETCHER/Sketcher_Profile.hxx | 10 +- src/SKETCHER/Sketcher_Utils.cxx | 187 ++++++++++++++++++++ src/SKETCHER/Sketcher_Utils.hxx | 97 ++++++++++ 15 files changed, 874 insertions(+), 14 deletions(-) create mode 100644 src/GEOMImpl/GEOMImpl_IPolyline2D.cxx create mode 100644 src/GEOMImpl/GEOMImpl_IPolyline2D.hxx mode change 100755 => 100644 src/GEOMImpl/GEOMImpl_Types.hxx create mode 100644 src/SKETCHER/Sketcher.hxx create mode 100644 src/SKETCHER/Sketcher_Utils.cxx create mode 100644 src/SKETCHER/Sketcher_Utils.hxx diff --git a/src/GEOM/GEOM_Function.cxx b/src/GEOM/GEOM_Function.cxx index db4658cf2..1474e8adf 100644 --- a/src/GEOM/GEOM_Function.cxx +++ b/src/GEOM/GEOM_Function.cxx @@ -36,6 +36,8 @@ #include #include #include +#include +#include #include #include #include @@ -476,6 +478,74 @@ Handle(TColStd_HArray1OfInteger) GEOM_Function::GetIntegerArray(int thePosition) return anIntegerArray->Array(); } +//============================================================================= +/*! + * SetByteArray + */ +//============================================================================= +void GEOM_Function::SetByteArray (int thePosition, + const Handle(TColStd_HArray1OfByte)& theArray) +{ + _isDone = false; + if(thePosition <= 0) return; + TDF_Label anArgLabel = ARGUMENT(thePosition); + Handle(TDataStd_ByteArray) anAttr = + TDataStd_ByteArray::Set(anArgLabel, theArray->Lower(), theArray->Upper()); + anAttr->ChangeArray(theArray); + _isDone = true; +} + +//============================================================================= +/*! + * GetByteArray + */ +//============================================================================= +Handle(TColStd_HArray1OfByte) GEOM_Function::GetByteArray(int thePosition) +{ + _isDone = false; + if(thePosition <= 0) return 0; + Handle(TDataStd_ByteArray) aByteArray; + TDF_Label anArgLabel = ARGUMENT(thePosition); + if(!anArgLabel.FindAttribute(TDataStd_ByteArray::GetID(), aByteArray)) return 0; + + _isDone = true; + return aByteArray->InternalArray(); +} + +//============================================================================= +/*! + * SetBooleanArray + */ +//============================================================================= +void GEOM_Function::SetBooleanArray (int thePosition, + const Handle(TColStd_HArray1OfByte)& theArray) +{ + _isDone = false; + if(thePosition <= 0) return; + TDF_Label anArgLabel = ARGUMENT(thePosition); + Handle(TDataStd_BooleanArray) anAttr = + TDataStd_BooleanArray::Set(anArgLabel, theArray->Lower(), theArray->Upper()); + anAttr->SetInternalArray(theArray); + _isDone = true; +} + +//============================================================================= +/*! + * GetBooleanArray + */ +//============================================================================= +Handle(TColStd_HArray1OfByte) GEOM_Function::GetBooleanArray(int thePosition) +{ + _isDone = false; + if(thePosition <= 0) return 0; + Handle(TDataStd_BooleanArray) aBooleanArray; + TDF_Label anArgLabel = ARGUMENT(thePosition); + if(!anArgLabel.FindAttribute(TDataStd_BooleanArray::GetID(), aBooleanArray)) return 0; + + _isDone = true; + return aBooleanArray->InternalArray(); +} + //============================================================================= /*! * SetString diff --git a/src/GEOM/GEOM_Function.hxx b/src/GEOM/GEOM_Function.hxx index 702acb959..688324dae 100644 --- a/src/GEOM/GEOM_Function.hxx +++ b/src/GEOM/GEOM_Function.hxx @@ -32,6 +32,7 @@ #include #include +class Handle_TColStd_HArray1OfByte; class Handle_TColStd_HArray1OfReal; class Handle_TColStd_HArray1OfInteger; class Handle_TColStd_HSequenceOfTransient; @@ -108,6 +109,18 @@ public: //Returns an integer array argument at position thePosition Standard_EXPORT Handle(TColStd_HArray1OfInteger) GetIntegerArray(int thePosition); + //Sets a byte array argument at position thePosition + Standard_EXPORT void SetByteArray(int thePosition, const Handle(TColStd_HArray1OfByte)& theArray); + + //Returns a byte array argument at position thePosition + Standard_EXPORT Handle(TColStd_HArray1OfByte) GetByteArray(int thePosition); + + //Sets a boolean array argument at position thePosition + Standard_EXPORT void SetBooleanArray(int thePosition, const Handle(TColStd_HArray1OfByte)& theArray); + + //Returns a boolean array argument at position thePosition + Standard_EXPORT Handle(TColStd_HArray1OfByte) GetBooleanArray(int thePosition); + //Sets a reference to other function argument at position thePosition Standard_EXPORT void SetReference(int thePosition, Handle(GEOM_Function) theReference); diff --git a/src/GEOMImpl/CMakeLists.txt b/src/GEOMImpl/CMakeLists.txt index 854c54755..5b6598f0d 100755 --- a/src/GEOMImpl/CMakeLists.txt +++ b/src/GEOMImpl/CMakeLists.txt @@ -72,6 +72,7 @@ SET(GEOMImpl_HEADERS GEOMImpl_PointDriver.hxx GEOMImpl_IPoint.hxx GEOMImpl_IPolyline.hxx + GEOMImpl_IPolyline2D.hxx GEOMImpl_ICircle.hxx GEOMImpl_ISpline.hxx GEOMImpl_IEllipse.hxx @@ -190,6 +191,7 @@ SET(GEOMImpl_SOURCES GEOMImpl_IMeasureOperations.cxx GEOMImpl_IGroupOperations.cxx GEOMImpl_IFieldOperations.cxx + GEOMImpl_IPolyline2D.cxx GEOMImpl_Gen.cxx GEOMImpl_PointDriver.cxx GEOMImpl_VectorDriver.cxx diff --git a/src/GEOMImpl/GEOMImpl_ICurvesOperations.cxx b/src/GEOMImpl/GEOMImpl_ICurvesOperations.cxx index 12f1a64dc..bdc090cdb 100644 --- a/src/GEOMImpl/GEOMImpl_ICurvesOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_ICurvesOperations.cxx @@ -51,6 +51,7 @@ #include "GEOMImpl_3DSketcherDriver.hxx" #include "GEOMImpl_IPolyline.hxx" +#include "GEOMImpl_IPolyline2D.hxx" #include "GEOMImpl_ICircle.hxx" #include "GEOMImpl_ISpline.hxx" #include "GEOMImpl_IEllipse.hxx" @@ -65,6 +66,7 @@ #include "utilities.h" #include +#include #include #include @@ -1512,8 +1514,53 @@ Handle(GEOM_Object) GEOMImpl_ICurvesOperations::MakePolyline2D const Handle(TColStd_HArray1OfByte) &theCloseds, const Handle(TColStd_HArray1OfReal) &theWorkingPlane) { - Handle(GEOM_Object) aResult; + SetErrorCode(KO); + + if (theCoords.empty() || theNames.IsNull() || theTypes.IsNull() || + theCloseds.IsNull() || theWorkingPlane.IsNull()) { + return NULL; + } + + // Add a new Polyline object + Handle(GEOM_Object) aResult = + GetEngine()->AddObject(GetDocID(), GEOM_POLYLINE2D); + Handle(GEOM_Function) aFunction = aResult->AddFunction + (GEOMImpl_PolylineDriver::GetID(), POLYLINE2D_PLN_COORDS); + + if (aFunction.IsNull()) { + return NULL; + } + + // Check if the function is set correctly + if (aFunction->GetDriverGUID() != GEOMImpl_PolylineDriver::GetID()) { + return NULL; + } + + GEOMImpl_IPolyline2D aCI(aFunction); + + aCI.SetCoords(theCoords); + aCI.SetNames(theNames); + aCI.SetTypes(theTypes); + aCI.SetClosedFlags(theCloseds); + aCI.SetWorkingPlaneDbls(theWorkingPlane); + + // Compute the isoline curve + try { +#if OCC_VERSION_LARGE > 0x06010000 + OCC_CATCH_SIGNALS; +#endif + if (!GetSolver()->ComputeFunction(aFunction)) { + SetErrorCode("Polyline driver failed"); + return NULL; + } + } + catch (Standard_Failure) { + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + SetErrorCode(aFail->GetMessageString()); + return NULL; + } + SetErrorCode(OK); return aResult; } @@ -1529,7 +1576,58 @@ Handle(GEOM_Object) GEOMImpl_ICurvesOperations::MakePolyline2DOnPlane const Handle(TColStd_HArray1OfByte) &theCloseds, const Handle(GEOM_Object) &theWorkingPlane) { - Handle(GEOM_Object) aResult; + SetErrorCode(KO); + + if (theCoords.empty() || theNames.IsNull() || theTypes.IsNull() || + theCloseds.IsNull() || theWorkingPlane.IsNull()) { + return NULL; + } + //Add a new Polyline object + Handle(GEOM_Object) aResult = + GetEngine()->AddObject(GetDocID(), GEOM_POLYLINE2D); + Handle(GEOM_Function) aFunction = aResult->AddFunction + (GEOMImpl_PolylineDriver::GetID(), POLYLINE2D_PLN_OBJECT); + + if (aFunction.IsNull()) { + return NULL; + } + + //Check if the function is set correctly + if (aFunction->GetDriverGUID() != GEOMImpl_PolylineDriver::GetID()) { + return NULL; + } + + Handle(GEOM_Function) aRefPlane = theWorkingPlane->GetLastFunction(); + + if (aRefPlane.IsNull()) { + return NULL; + } + + GEOMImpl_IPolyline2D aCI(aFunction); + + aCI.SetCoords(theCoords); + aCI.SetNames(theNames); + aCI.SetTypes(theTypes); + aCI.SetClosedFlags(theCloseds); + aCI.SetWorkingPlane(aRefPlane); + + //Compute the isoline curve + try { +#if OCC_VERSION_LARGE > 0x06010000 + OCC_CATCH_SIGNALS; +#endif + if (!GetSolver()->ComputeFunction(aFunction)) { + SetErrorCode("Polyline driver failed"); + return NULL; + } + } + catch (Standard_Failure) { + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + SetErrorCode(aFail->GetMessageString()); + return NULL; + } + + SetErrorCode(OK); return aResult; } diff --git a/src/GEOMImpl/GEOMImpl_IPolyline2D.cxx b/src/GEOMImpl/GEOMImpl_IPolyline2D.cxx new file mode 100644 index 000000000..5cb94e0c1 --- /dev/null +++ b/src/GEOMImpl/GEOMImpl_IPolyline2D.cxx @@ -0,0 +1,125 @@ +// Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 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, or (at your option) any later version. +// +// 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 +// + + +#include "GEOMImpl_IPolyline2D.hxx" + +#include + + +//============================================================================= +/*! + * SetCoords + */ +//============================================================================= +void GEOMImpl_IPolyline2D::SetCoords + (const std::list > &theValue) +{ + // Compute the total number of points and fill the array of start indices. + Standard_Integer i; + const Standard_Integer aNbSec = theValue.size(); + Standard_Integer aNbCoords = 0; + Handle(TColStd_HArray1OfInteger) anIndices; + std::list >::const_iterator aSecIter; + + if (aNbSec == 1) { + // There is only one section. + aNbCoords = theValue.front().size(); + } else { + // Here we assume that there are more than one section. + anIndices = new TColStd_HArray1OfInteger(1, aNbSec - 1); + aSecIter = theValue.begin(); + aNbCoords += aSecIter->size(); + + for (i = 1, ++aSecIter; aSecIter != theValue.end(); ++aSecIter, ++i) { + anIndices->SetValue(i, aNbCoords + 1); + aNbCoords += aSecIter->size(); + } + } + + // Fill the array of coordinates. + Handle(TColStd_HArray1OfReal) aCoords = + new TColStd_HArray1OfReal(1, aNbCoords); + std::list::const_iterator aCIter; + + aSecIter = theValue.begin(); + + for (i = 1; aSecIter != theValue.end(); ++aSecIter) { + for (aCIter = aSecIter->begin(); aCIter != aSecIter->end(); ++aCIter) { + aCoords->SetValue(i++, *aCIter); + } + } + + // Store the coordinates. + _func->SetRealArray(POLY_ARG_COORDS, aCoords); + + if (anIndices.IsNull() == Standard_False) { + _func->SetIntegerArray(POLY_ARG_START_INDICES, anIndices); + } +} + +//============================================================================= +/*! + * GetCoords + */ +//============================================================================= +void GEOMImpl_IPolyline2D::GetCoords(std::list > &theValue) +{ + theValue.clear(); + + Handle(TColStd_HArray1OfReal) aCoords = + _func->GetRealArray(POLY_ARG_COORDS); + Handle(TColStd_HArray1OfInteger) anIndices = + _func->GetIntegerArray(POLY_ARG_START_INDICES); + + if (aCoords.IsNull() == Standard_False) { + std::list anEmptyList; + Standard_Integer i; + Standard_Integer iNextSec = 0; + Standard_Integer aNextSecIndex = aCoords->Upper() + 1; + + if (anIndices.IsNull() == Standard_False) { + iNextSec = anIndices->Lower(); + aNextSecIndex = anIndices->Value(iNextSec); + } + + theValue.push_back(anEmptyList); + + for (i = aCoords->Lower(); i <= aCoords->Upper(); ++i) { + // Check if it is necessary to create a new section. + // Assume a case if there are empty sections. + while (i == aNextSecIndex) { + // Create a next section. + theValue.push_back(anEmptyList); + ++iNextSec; + + if (iNextSec > anIndices->Upper()) { + aNextSecIndex = aCoords->Upper() + 1; + } else { + aNextSecIndex = anIndices->Value(iNextSec); + } + } + + theValue.back().push_back(aCoords->Value(i)); + } + } +} diff --git a/src/GEOMImpl/GEOMImpl_IPolyline2D.hxx b/src/GEOMImpl/GEOMImpl_IPolyline2D.hxx new file mode 100644 index 000000000..5992fcccf --- /dev/null +++ b/src/GEOMImpl/GEOMImpl_IPolyline2D.hxx @@ -0,0 +1,95 @@ +// Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 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, or (at your option) any later version. +// +// 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 +// + +//NOTE: This is an interface to a function for the Polyline2D creation. + + +#ifndef _GEOMImpl_IPolyline2D_HXX_ +#define _GEOMImpl_IPolyline2D_HXX_ + + +#include +#include + +#include + +#include +#include +#include + + +#define POLY_ARG_NAMES 1 +#define POLY_ARG_TYPES 2 +#define POLY_ARG_CLOSEDS 3 +#define POLY_ARG_COORDS 4 +#define POLY_ARG_START_INDICES 5 +#define POLY_ARG_WPLANE_DBLS 6 +#define POLY_ARG_WPLANE_OBJ 7 + + +class GEOMIMPL_EXPORT GEOMImpl_IPolyline2D +{ + public: + + GEOMImpl_IPolyline2D(Handle(GEOM_Function) theFunction): _func(theFunction) {} + + void SetNames(const Handle_TColStd_HArray1OfExtendedString &theValue) + { _func->SetStringArray(POLY_ARG_NAMES, theValue); } + + Handle_TColStd_HArray1OfExtendedString GetNames() + { return _func->GetStringArray(POLY_ARG_NAMES); } + + void SetTypes(const Handle_TColStd_HArray1OfByte &theValue) + { _func->SetByteArray(POLY_ARG_TYPES, theValue); } + + Handle_TColStd_HArray1OfByte GetTypes() + { return _func->GetByteArray(POLY_ARG_TYPES); } + + void SetClosedFlags(const Handle_TColStd_HArray1OfByte &theValue) + { _func->SetBooleanArray(POLY_ARG_CLOSEDS, theValue); } + + Handle_TColStd_HArray1OfByte GetClosedFlags() + { return _func->GetBooleanArray(POLY_ARG_CLOSEDS); } + + void SetWorkingPlaneDbls(const Handle_TColStd_HArray1OfReal &thePlane) + { _func->SetRealArray(POLY_ARG_WPLANE_DBLS, thePlane); } + + Handle_TColStd_HArray1OfReal GetWorkingPlaneDbls() + { return _func->GetRealArray(POLY_ARG_WPLANE_DBLS); } + + void SetWorkingPlane(const Handle_GEOM_Function &thePlane) + { _func->SetReference(POLY_ARG_WPLANE_OBJ, thePlane); } + + Handle_GEOM_Function GetWorkingPlane() + { return _func->GetReference(POLY_ARG_WPLANE_OBJ); } + + void SetCoords(const std::list > &theValue); + + void GetCoords(std::list > &theValue); + + private: + + Handle(GEOM_Function) _func; +}; + + +#endif diff --git a/src/GEOMImpl/GEOMImpl_PolylineDriver.cxx b/src/GEOMImpl/GEOMImpl_PolylineDriver.cxx index 1eeeaf277..1c182c9cb 100644 --- a/src/GEOMImpl/GEOMImpl_PolylineDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_PolylineDriver.cxx @@ -23,12 +23,17 @@ #include "GEOMImpl_PolylineDriver.hxx" #include "GEOMImpl_ICurveParametric.hxx" +#include "GEOMImpl_ICurvesOperations.hxx" #include "GEOMImpl_IPolyline.hxx" +#include "GEOMImpl_IPolyline2D.hxx" #include "GEOMImpl_Types.hxx" #include "GEOM_Function.hxx" +#include +#include #include #include +#include #include #include #include @@ -38,6 +43,7 @@ #include #include #include +#include #include //======================================================================= @@ -59,6 +65,124 @@ GEOMImpl_PolylineDriver::GEOMImpl_PolylineDriver() { } +//======================================================================= +//function : MakePolyline2D +//purpose : +//======================================================================= +Standard_Integer GEOMImpl_PolylineDriver::MakePolyline2D + (TFunction_Logbook& log) const +{ + if (Label().IsNull()) { + return 0; + } + + Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label()); + GEOMImpl_IPolyline2D aCI(aFunction); + Standard_Integer aType = aFunction->GetType(); + TopoDS_Shape aShape; + + // Get data. + Handle(TColStd_HArray1OfExtendedString) aNames = aCI.GetNames(); + Handle(TColStd_HArray1OfByte) aTypes = aCI.GetTypes(); + Handle(TColStd_HArray1OfByte) aClosedFlags = aCI.GetClosedFlags(); + std::list > aCoords; + gp_Ax3 aWPlane; + + aCI.GetCoords(aCoords); + + // Check the data validity + if (aNames.IsNull()) { + return 0; + } + + Standard_Integer aNbSections = aNames->Length(); + + if (aTypes.IsNull() || aNbSections != aTypes->Length()) { + return 0; + } + + if (aClosedFlags.IsNull() || aNbSections != aClosedFlags->Length()) { + return 0; + } + + if (aNbSections != aCoords.size()) { + return 0; + } + + if (aType == POLYLINE2D_PLN_COORDS) { + Handle(TColStd_HArray1OfReal) aPlaneCoords = aCI.GetWorkingPlaneDbls(); + + if (aPlaneCoords.IsNull()) { + return 0; + } + + if (aPlaneCoords->Length() != 9) { + return 0; + } + + Standard_Integer i = aPlaneCoords->Lower(); + gp_Pnt aOrigin(aPlaneCoords->Value(i), aPlaneCoords->Value(i + 1), + aPlaneCoords->Value(i + 2)); + gp_Dir aDirZ(aPlaneCoords->Value(i + 3), aPlaneCoords->Value(i + 4), + aPlaneCoords->Value(i + 5)); + gp_Dir aDirX(aPlaneCoords->Value(i + 6), aPlaneCoords->Value(i + 7), + aPlaneCoords->Value(i + 8)); + aWPlane = gp_Ax3(aOrigin, aDirZ, aDirX); + } else if (aType == POLYLINE2D_PLN_COORDS) { + Handle(GEOM_Function) aRefFace = aCI.GetWorkingPlane(); + TopoDS_Shape aShape = aRefFace->GetValue(); + + aWPlane = GEOMUtils::GetPosition(aShape); + } else { + return 0; + } + + // Construct a shape. + Standard_Integer iN = aNames->Lower(); + Standard_Integer iT = aTypes->Lower(); + Standard_Integer iC = aClosedFlags->Lower(); + std::list >::const_iterator anIter = aCoords.begin(); + BRep_Builder aBuilder; + + if (aNbSections > 1) { + aBuilder.MakeCompound(TopoDS::Compound(aShape)); + } + + for (; anIter != aCoords.end(); ++anIter, ++iN, ++iT, ++iC) { + Standard_Integer aType = aTypes->Value(iT); + TopoDS_Shape aSection; + + if (aType == GEOMImpl_ICurvesOperations::Polyline) { + aSection = Sketcher_Utils::MakePolyline + (*anIter, aClosedFlags->Value(iC), aWPlane); + } else if (aType == GEOMImpl_ICurvesOperations::Interpolation) { + aSection = Sketcher_Utils::MakeInterpolation + (*anIter, aClosedFlags->Value(iC), aWPlane); + } + + if (aSection.IsNull()) { + return 0; + } + + if (aNbSections > 1) { + // There are multiple sections. + aBuilder.Add(aShape, aSection); + } else { + // There is only one section. + aShape = aSection; + } + } + + if (aShape.IsNull()) { + return 0; + } + + aFunction->SetValue(aShape); + log.SetTouched(Label()); + + return 1; +} + //======================================================================= //function : Execute //purpose : @@ -67,9 +191,13 @@ Standard_Integer GEOMImpl_PolylineDriver::Execute(TFunction_Logbook& log) const { if (Label().IsNull()) return 0; Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label()); + Standard_Integer aType = aFunction->GetType(); + + if (aType == POLYLINE2D_PLN_COORDS || aType == POLYLINE2D_PLN_OBJECT) { + return MakePolyline2D(log); + } GEOMImpl_IPolyline aCI (aFunction); - Standard_Integer aType = aFunction->GetType(); TopoDS_Shape aShape; diff --git a/src/GEOMImpl/GEOMImpl_PolylineDriver.hxx b/src/GEOMImpl/GEOMImpl_PolylineDriver.hxx index 3f8165537..b3f89d91e 100644 --- a/src/GEOMImpl/GEOMImpl_PolylineDriver.hxx +++ b/src/GEOMImpl/GEOMImpl_PolylineDriver.hxx @@ -80,6 +80,9 @@ Standard_EXPORT ~GEOMImpl_PolylineDriver() {}; Standard_EXPORT virtual bool GetCreationInformation(std::string& theOperationName, std::vector& params); +private: + + Standard_Integer MakePolyline2D(TFunction_Logbook& log) const; DEFINE_STANDARD_RTTI( GEOMImpl_PolylineDriver ) }; diff --git a/src/GEOMImpl/GEOMImpl_Types.hxx b/src/GEOMImpl/GEOMImpl_Types.hxx old mode 100755 new mode 100644 index 4f4792448..4ee695c3e --- a/src/GEOMImpl/GEOMImpl_Types.hxx +++ b/src/GEOMImpl/GEOMImpl_Types.hxx @@ -113,6 +113,8 @@ #define GEOM_ISOLINE 55 +#define GEOM_POLYLINE2D 56 + //GEOM_Function types #define COPY_WITH_REF 1 @@ -365,5 +367,8 @@ #define IMPORTEXPORT_EXPORTXAO 1 #define IMPORTEXPORT_IMPORTXAO 2 +#define POLYLINE2D_PLN_COORDS 1 +#define POLYLINE2D_PLN_OBJECT 2 + // Advanced functions (base = 200) #define ADVANCED_BASE 200 // NO OPERATION (advanced operations base) diff --git a/src/GEOM_SWIG/gsketcher.py b/src/GEOM_SWIG/gsketcher.py index 0171adaf0..004e8e63e 100644 --- a/src/GEOM_SWIG/gsketcher.py +++ b/src/GEOM_SWIG/gsketcher.py @@ -1251,7 +1251,7 @@ class Polyline2D: # @param theClosed True for closed section; False otherwise # @param thePoints the list of 2D points coordinates in the form: # [x1, y1, x2, y2, ..., xN, yN] for N points. - def addSection(self, theName, theType, theClosed, thePoints = []): + def addSection(self, theName, theType, theClosed, thePoints = None): """ Add a new section to the polyline. @@ -1273,7 +1273,10 @@ class Polyline2D: self.myNameList.append(theName) self.myTypeList.append(EnumToLong(theType)) self.myClosedList.append(theClosed) - self.myCoordsList.append(thePoints) + if thePoints is None: + self.myCoordsList.append([]) + else: + self.myCoordsList.append(thePoints) pass ## Add a points to the last added section of the polyline. If there are diff --git a/src/SKETCHER/CMakeLists.txt b/src/SKETCHER/CMakeLists.txt index 257c2dd1e..ef7e87480 100755 --- a/src/SKETCHER/CMakeLists.txt +++ b/src/SKETCHER/CMakeLists.txt @@ -43,13 +43,16 @@ SET(_link_LIBRARIES # --- headers --- SET(SKETCHER_HEADERS + Sketcher.hxx Sketcher_Profile.hxx + Sketcher_Utils.hxx ) # --- sources --- SET(SKETCHER_SOURCES Sketcher_Profile.cxx + Sketcher_Utils.cxx ) # --- rules --- diff --git a/src/SKETCHER/Sketcher.hxx b/src/SKETCHER/Sketcher.hxx new file mode 100644 index 000000000..175dce9b1 --- /dev/null +++ b/src/SKETCHER/Sketcher.hxx @@ -0,0 +1,39 @@ +// Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 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, or (at your option) any later version. +// +// 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 : Sketcher.hxx +// Author : Sergey KHROMOV + +#ifndef SKETCHER_HXX +#define SKETCHER_HXX + +#if defined WIN32 +# if defined SKETCHER_SALOME_EXPORTS || defined SKETCHER_EXPORTS || defined GEOMSketcher_EXPORTS || defined GEOMSKETCHER_EXPORTS +# define SKETCHER_SALOME_EXPORT _declspec( dllexport ) +# else +# define SKETCHER_SALOME_EXPORT _declspec( dllimport ) +# endif +#else +# define SKETCHER_SALOME_EXPORT +#endif + +#endif // SKETCHER_HXX \ No newline at end of file diff --git a/src/SKETCHER/Sketcher_Profile.hxx b/src/SKETCHER/Sketcher_Profile.hxx index ed792f83b..4ff689ac4 100644 --- a/src/SKETCHER/Sketcher_Profile.hxx +++ b/src/SKETCHER/Sketcher_Profile.hxx @@ -23,16 +23,8 @@ // File : Sketcher_Profile.h // Author : Damien COQUERET -#if defined WIN32 -# if defined SKETCHER_SALOME_EXPORTS || defined SKETCHER_EXPORTS || defined GEOMSketcher_EXPORTS || defined GEOMSKETCHER_EXPORTS -# define SKETCHER_SALOME_EXPORT _declspec( dllexport ) -# else -# define SKETCHER_SALOME_EXPORT _declspec( dllimport ) -# endif -#else -# define SKETCHER_SALOME_EXPORT -#endif +#include "Sketcher.hxx" #include #include #include diff --git a/src/SKETCHER/Sketcher_Utils.cxx b/src/SKETCHER/Sketcher_Utils.cxx new file mode 100644 index 000000000..725a985cf --- /dev/null +++ b/src/SKETCHER/Sketcher_Utils.cxx @@ -0,0 +1,187 @@ +// Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 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, or (at your option) any later version. +// +// 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 : Sketcher_Utils.cxx +// Author : Sergey KHROMOV +// Module : GEOM + + +#include "Sketcher_Utils.hxx" + +#include +#include +#include +#include +#include +#include +#include + +const double POINT_CONFUSION_TOLERANCE = 0.0001; + + +//======================================================================= +// function : MakePolyline +// purpose : +//======================================================================= +TopoDS_Shape Sketcher_Utils::MakePolyline + (const std::list &theCoords2D, + const Standard_Boolean IsClosed, + const gp_Ax3 &thePlane) +{ + std::list aPoints; + TopoDS_Shape aResult; + + To3D(theCoords2D, thePlane, aPoints); + + Standard_Integer aNbPnts = aPoints.size(); + + if (aNbPnts > 1) { + if (IsClosed && + aPoints.front().IsEqual(aPoints.back(), POINT_CONFUSION_TOLERANCE)) { + // The polyline should be closed, first and last points are confused. + // Remove the last point. + aPoints.pop_back(); + --aNbPnts; + } + } + + if (aNbPnts == 1) { + // The result is vertex. + aResult = BRepBuilderAPI_MakeVertex(aPoints.front()).Vertex(); + } else if (aNbPnts > 1) { + // There are several points. Make a polyline. + std::list ::const_iterator anIter = aPoints.begin(); + TopoDS_Vertex aVtxFirst = + BRepBuilderAPI_MakeVertex(*anIter).Vertex(); + TopoDS_Vertex aVtx[2]; + TopoDS_Edge aSegment; + BRepBuilderAPI_MakeWire aMkWire; + + aVtx[0] = aVtxFirst; + + for (++anIter; anIter != aPoints.end(); ++anIter) { + aVtx[1] = BRepBuilderAPI_MakeVertex(*anIter).Vertex(); + aSegment = BRepBuilderAPI_MakeEdge(aVtx[0], aVtx[1]).Edge(); + aMkWire.Add(aSegment); + aVtx[0] = aVtx[1]; + } + + if (IsClosed) { + // Create a closing segment. + aSegment = BRepBuilderAPI_MakeEdge(aVtx[0], aVtxFirst).Edge(); + aMkWire.Add(aSegment); + } + + aResult = aMkWire.Wire(); + } + + return aResult; +} + +//======================================================================= +// function : MakeInterpolation +// purpose : +//======================================================================= +TopoDS_Shape Sketcher_Utils::MakeInterpolation + (const std::list &theCoords2D, + const Standard_Boolean IsClosed, + const gp_Ax3 &thePlane) +{ + std::list aPoints; + TopoDS_Shape aResult; + + To3D(theCoords2D, thePlane, aPoints); + + Standard_Integer aNbPnts = aPoints.size(); + + if (aNbPnts > 1) { + if (IsClosed && + aPoints.front().IsEqual(aPoints.back(), POINT_CONFUSION_TOLERANCE)) { + // The polyline should be closed, first and last points are confused. + // Remove the last point. + aPoints.pop_back(); + --aNbPnts; + } + } + + if (aNbPnts == 1) { + // The result is vertex. + aResult = BRepBuilderAPI_MakeVertex(aPoints.front()).Vertex(); + } else if (aNbPnts > 1) { + std::list ::const_iterator anIter = aPoints.begin(); + Handle(TColgp_HArray1OfPnt) aHCurvePoints = + new TColgp_HArray1OfPnt(1, aNbPnts); + Standard_Integer i; + + for (i = 1; anIter != aPoints.end(); ++anIter, ++i) { + aHCurvePoints->SetValue(i, *anIter); + } + + // Compute BSpline + Standard_Real aTol = Precision::Confusion(); + GeomAPI_Interpolate aGBC(aHCurvePoints, IsClosed, aTol); + + aGBC.Perform(); + + if (aGBC.IsDone()) { + TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge(aGBC.Curve()).Edge(); + aResult = BRepBuilderAPI_MakeWire(anEdge).Wire(); + } + } + + return aResult; +} + +//======================================================================= +// function : To3D +// purpose : +//======================================================================= +void Sketcher_Utils::To3D(const std::list &theCoords2D, + const gp_Ax3 &thePlane, + std::list &thePoints) +{ + thePoints.clear(); + + if (theCoords2D.empty() || theCoords2D.size() % 2 == 1) { + // Odd number of coordinates or empty list. Invalid case. + return; + } + + std::list ::const_iterator anIter = theCoords2D.begin(); + Standard_Real aX = *anIter; + Standard_Real aY = *(++anIter); + gp_Pnt aPLast = ElSLib::PlaneValue (aX, aY, thePlane); + gp_Pnt aPnt; + + thePoints.push_back(aPLast); + + for (++anIter; anIter != theCoords2D.end(); ++anIter) { + aX = *anIter; + aY = *(++anIter); + aPnt = ElSLib::PlaneValue (aX, aY, thePlane); + + if (!aPLast.IsEqual(aPnt, POINT_CONFUSION_TOLERANCE)) { + thePoints.push_back(aPnt); + aPLast = aPnt; + } + } +} diff --git a/src/SKETCHER/Sketcher_Utils.hxx b/src/SKETCHER/Sketcher_Utils.hxx new file mode 100644 index 000000000..871a1ac54 --- /dev/null +++ b/src/SKETCHER/Sketcher_Utils.hxx @@ -0,0 +1,97 @@ +// Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 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, or (at your option) any later version. +// +// 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 : Sketcher_Utils.h +// Author : Sergey KHROMOV + + +#include "Sketcher.hxx" + +#include +#include + +#include + + +class gp_Ax3; + + +/** + * This class represents a set of utils needed to compute sketcher geometry. + */ +class SKETCHER_SALOME_EXPORT Sketcher_Utils +{ + +public: + + /** + * This method makes a shape from the list of 2D coordinates on the working + * plane. The result represents a vertex if there is only one point + * in the contour. If there are more then one points the result is a wire + * consisting of linear segments between points. It is either closed or not + * depending on the flag IsClosed. In case of failure the result is a null + * shape. + * + * \param theCoords2D is the list of coordinates in the form x1, y1, x2, y2, + * ..., xN, yN for N 2D points. + * \param IsClosed if Standard_True the first and last points are connected + * to form the closed contour. + * \param thePlane the working plane coordinate system. + * \return the result polyline. + */ + static TopoDS_Shape MakePolyline(const std::list &theCoords2D, + const Standard_Boolean IsClosed, + const gp_Ax3 &thePlane); + + /** + * This method makes a shape from the list of 2D coordinates on the working + * plane. The result represents a vertex if there is only one point + * in the contour. If there are more then one points the result is a wire + * consisting of a points interpolation BSpline curve. It is either closed + * or not depending on the flag IsClosed. In case of failure the result is + * a null shape. + * + * \param theCoords2D is the list of coordinates in the form x1, y1, x2, y2, + * ..., xN, yN for N 2D points. + * \param IsClosed if Standard_True the first and last points are connected + * to form the closed contour. + * \param thePlane the working plane coordinate system. + * \return the result interpolation wire. + */ + static TopoDS_Shape MakeInterpolation(const std::list &theCoords2D, + const Standard_Boolean IsClosed, + const gp_Ax3 &thePlane); + + /** + * This method converts the list of 2D point coordinates into 3D points + * basing on the working plane. The result list contains not confused points. + * + * \param theCoords2D is the list of coordinates in the form x1, y1, x2, y2, + * ..., xN, yN for N 2D points. + * \param thePlane the working plane coordinate system. + * \param thePoints the list of 3D points. + */ + static void To3D(const std::list &theCoords2D, + const gp_Ax3 &thePlane, + std::list &thePoints); + +}; -- 2.39.2