// 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 "GEOM_Field.hxx" #include "GEOM_IField.hxx" #include "GEOM_Engine.hxx" #include "GEOM_PythonDump.hxx" #include #include #include #include #include #include #include #include #include #include "utilities.h" #include using namespace GEOM; namespace { //================================================================================ /*! * \brief Returns a funtion with a given type OR the 1st function */ //================================================================================ Handle(GEOM_Function) getFunction(int theFunType, GEOM_BaseObject* obj ) { Handle(GEOM_Function) fun; int nbFuns = obj->GetNbFunctions(); while ( nbFuns >= 1 ) { fun = obj->GetFunction( nbFuns-- ); const int funType = fun->GetType(); if ( funType == theFunType ) return fun; } return fun; // function 1 } } //============================================================================= /*! * Constructor: private */ //============================================================================= GEOM_Field::GEOM_Field(const TDF_Label& theEntry) : GEOM_BaseObject(theEntry), nbSubShapes(-1) { } //============================================================================= /*! * Constructor: public */ //============================================================================= GEOM_Field::GEOM_Field(const TDF_Label& theEntry, int /*typ*/) : GEOM_BaseObject( theEntry, GEOM_FIELD_OBJTYPE ), nbSubShapes(-1) { } //================================================================================ /*! * \brief Sets the basic data that do not change (except compNames?) */ //================================================================================ void GEOM_Field::Init(const Handle(GEOM_Object)& theShape, const char* theName, const int theDataType, const int theDimension, const Handle(TColStd_HArray1OfExtendedString)& theCompNames) { Handle(GEOM_Function) fun = GetFunction(1); if ( !fun.IsNull() ) Standard_MultiplyDefined::Raise( "Reinitialization of GEOM_Field is forbiden" ); fun = AddFunction( GetFieldID(), FUN_ADD_FIELD ); GEOM_IField data( fun ); data.SetShape ( theShape->GetLastFunction() ); data.SetDataType ( theDataType ); data.SetDimension ( theDimension ); data.SetComponents( theCompNames ); TPythonDump py( fun ); // prevent dump of SetName SetName( theName ); // PythonDump to be done by the operation creating this field } //============================================================================= /*! * GetField */ //============================================================================= Handle(GEOM_Field) GEOM_Field::GetField(const TDF_Label& theLabel) { Handle(GEOM_BaseObject) base = GEOM_BaseObject::GetObject(theLabel); return Handle(GEOM_Field)::DownCast( base ); } //======================================================================= //function : GetFieldID //purpose : //======================================================================= const Standard_GUID& GEOM_Field::GetFieldID() { static Standard_GUID anID("FF1BBB01-5252-4df2-980B-3A668264EA16"); return anID; } //============================================================================= /*! * Destructor */ //============================================================================= GEOM_Field::~GEOM_Field() { } //============================================================================= /*! * Returns a shape this GEOM_Field lies on */ //============================================================================= Handle(GEOM_Object) GEOM_Field::GetShape() { Handle(GEOM_Object) shapeObject; Handle(GEOM_Function) fun = GetFunction(1); if ( !fun.IsNull() ) { GEOM_IField data( fun ); Handle(GEOM_Function) shapeFun = data.GetShape(); if ( !shapeFun.IsNull() ) { TDF_Label shapeLabel = shapeFun->GetOwnerEntry(); shapeObject = GEOM_Object::GetObject( shapeLabel ); } } return shapeObject; } //======================================================================= //function : GetNbSubShapes //purpose : Returns number of sub-shapes. // Size of data arrays == GetNbSubShapes() * GetComponents()->Extent() //======================================================================= int GEOM_Field::GetNbSubShapes() { if ( nbSubShapes < 0 ) nbSubShapes = GetNbSubShapes( GetShape(), GetDimension() ); return nbSubShapes; } //======================================================================= //function : GetNbSubShapes //purpose : Returns number of sub-shapes of given dimension //======================================================================= int GEOM_Field::GetNbSubShapes(const Handle(GEOM_Object)& shObj, const int dim) { int nbSubShapes = 0; if ( shObj.IsNull() ) return nbSubShapes; TopoDS_Shape shape = shObj->GetValue(); if (shape.IsNull() ) return nbSubShapes; if ( dim == -1 ) { nbSubShapes = 1; } else { TopAbs_ShapeEnum type; switch( dim ) { case 0: type = TopAbs_VERTEX; break; case 1: type = TopAbs_EDGE; break; case 2: type = TopAbs_FACE; break; case 3: type = TopAbs_SOLID; break; default: return nbSubShapes; } TopTools_IndexedMapOfShape map; TopExp::MapShapes( shape, type, map ); nbSubShapes = map.Extent(); } return nbSubShapes; } //======================================================================= //function : GetNbComponents //purpose : Returns number of components //======================================================================= int GEOM_Field::GetNbComponents() { Handle(TColStd_HArray1OfExtendedString) comps = GetComponents(); return comps.IsNull() ? 0 : comps->Length(); } //======================================================================= //function : GetArrayLength //purpose : Returns size of data array == GetNbSubShapes() * GetComponents()->Extent() //======================================================================= int GEOM_Field::GetArrayLength() { return GetNbComponents() * GetNbSubShapes(); } //======================================================================= //function : GetDataType //purpose : Returns a data type of this GEOM_Field //======================================================================= int GEOM_Field::GetDataType() { Handle(GEOM_Function) fun = GetFunction(1); if ( !fun.IsNull() ) return GEOM_IField( fun ).GetDataType(); return -1; } //======================================================================= //function : GetDataTypeString //purpose : Returns one of "Bool","Int","Double","String" //======================================================================= TCollection_AsciiString GEOM_Field::GetDataTypeString(int type) { const char* typeNames[] = { "Bool","Int","Double","String" }; if ( type < 0 || type > 3 ) return type; return typeNames[ type ]; } //======================================================================= //function : GetDimension //purpose : Returns dimension of the shape the field lies on: // 0 - VERTEX, 1 - EDGE, 2 - FACE, 3 - SOLID, -1 - whole shape //======================================================================= int GEOM_Field::GetDimension() { Handle(GEOM_Function) fun = GetFunction(1); if ( !fun.IsNull() ) return GEOM_IField( fun ).GetDimension(); return -1; } //======================================================================= //function : SetComponents //purpose : Sets names of components //======================================================================= void GEOM_Field::SetComponents( const Handle(TColStd_HArray1OfExtendedString)& compNames ) { // By spec. modification of components is not required, but just in case... Handle(GEOM_Function) fun = GetLastFunction(); if ( fun->GetType() != FUN_ADD_FIELD ) { fun = AddFunction( GetFieldID(), FUN_CHANGE_COMP_NAMES ); //TPythonDump( fun ) << this << ".setComponents( " } GEOM_IField data( fun ); data.SetComponents( compNames ); } //======================================================================= //function : GetComponents //purpose : Returns names of components //======================================================================= Handle(TColStd_HArray1OfExtendedString) GEOM_Field::GetComponents() { Handle(GEOM_Function) fun = getFunction( FUN_CHANGE_COMP_NAMES, this ); if ( !fun.IsNull() ) return GEOM_IField( fun ).GetComponents(); return NULL; } //======================================================================= //function : getFunctionToSetValues //purpose : dump any HArray into a string //======================================================================= template< class Handle_HARRAY1 > TCollection_AsciiString arrayToSting( const Handle_HARRAY1& ar, const char* quote="") { TCollection_AsciiString s; char prefix[] = "[ "; if ( !ar.IsNull() ) for ( int i = ar->Lower(), nb = ar->Upper(); i <= nb; ++i ) { s += prefix; s += quote; s += TCollection_AsciiString( ar->Value( i )); s += quote; prefix[0] = ','; } if ( !s.IsEmpty() ) s += " ]"; return s; } //======================================================================= //function : GetComponentsForPython //purpose : Returns names of components in a python syntax //======================================================================= TCollection_AsciiString GEOM_Field::GetComponentsForPython() { return arrayToSting( GetComponents(), "'" ); } //======================================================================= //function : AddStep //purpose : Adds a step //======================================================================= Handle(GEOM_FieldStep) GEOM_Field::AddStep(const int stepID, const int stamp) { Handle(GEOM_FieldStep) step = GetStep( stepID ); if ( !step.IsNull() ) return NULL; GEOM_Engine* anEngine = GEOM_Engine::GetEngine(); if(anEngine == NULL) return NULL; step = Handle(GEOM_FieldStep)::DownCast ( anEngine->AddBaseObject( GetDocID(),GEOM_FIELD_STEP_OBJTYPE )); if ( step.IsNull()) return step; // set all step data Handle(GEOM_Field) field = GEOM_Field::GetField( GetEntry() ); step->Init( field, stepID, stamp ); Handle(TDataStd_TreeNode) aRoot, aNode; aRoot = TDataStd_TreeNode::Set( GetEntry(), GetFieldID() ); aNode = TDataStd_TreeNode::Set( step->GetEntry(), GetFieldID() ); aRoot->Append(aNode); // Dump just in case if step.SetValues() would fail which normally // replaces this dump. // field.addStep(step, stamp, values) TCollection_AsciiString defaultVal( GetDataType() == 3 ? "''" : "0" ); TPythonDump( step->GetFunction(1) ) << step << " = " << this << ".addStep( " << stepID << ", " << stamp << ", " << "[" << defaultVal << "]*" << GetArrayLength() << " )"; return step; } //======================================================================= //function : RemoveStep //purpose : Removes a step //======================================================================= void GEOM_Field::RemoveStep(const int stepID) { Handle(GEOM_FieldStep) step = GetStep( stepID ); if ( step.IsNull() ) return; Handle(TDataStd_TreeNode) aNode = TDataStd_TreeNode::Set( step->GetEntry(), GetFieldID() ); aNode->Remove(); // Removes this tree node attribute from its father // Dump of removed objects is not produced anayway //Handle(GEOM_Function) fun = AddFunction( GetFieldID(), FUN_REMOVE_STEP ); //TPythonDump( fun ) << this << ".removeStep( " << stepID << " )"; GEOM_Engine* anEngine = GEOM_Engine::GetEngine(); if ( anEngine ) anEngine->RemoveObject( step ); } //======================================================================= //function : GetStep //purpose : Returns a step //======================================================================= Handle(GEOM_FieldStep) GEOM_Field::GetStep(const int stepID) { Handle(GEOM_FieldStep) step; Handle(TDataStd_TreeNode) aRoot, aNode; if ( !GetEntry().FindAttribute( GetFieldID(), aRoot )) return step; TDataStd_ChildNodeIterator anIter (aRoot); for (; anIter.More(); anIter.Next()) { aNode = anIter.Value(); step = GEOM_FieldStep::GetFieldStep( aNode->Label() ); if ( !step.IsNull() && step->GetID() == stepID ) return step; } return NULL; } //======================================================================= //function : GetSteps //purpose : Returns all steps //======================================================================= std::list< Handle(GEOM_FieldStep)> GEOM_Field::GetSteps() { std::list< Handle(GEOM_FieldStep) > stepList; Handle(TDataStd_TreeNode) aRoot, aNode; if ( !GetEntry().FindAttribute( GetFieldID(), aRoot )) return stepList; Handle(GEOM_FieldStep) step; TDataStd_ChildNodeIterator anIter (aRoot); for (; anIter.More(); anIter.Next()) { aNode = anIter.Value(); step = GEOM_FieldStep::GetFieldStep( aNode->Label() ); if ( !step.IsNull() ) stepList.push_back( step ); } return stepList; } //============================================================================= /*! * Constructor: private */ //============================================================================= GEOM_FieldStep::GEOM_FieldStep(const TDF_Label& theEntry) : GEOM_BaseObject(theEntry) { } //============================================================================= /*! * Constructor: public */ //============================================================================= GEOM_FieldStep::GEOM_FieldStep(const TDF_Label& theLabel, int /*type*/ ) : GEOM_BaseObject( theLabel, GEOM_FIELD_STEP_OBJTYPE ) { } //================================================================================ /*! * \brief Sets the basic data */ //================================================================================ void GEOM_FieldStep::Init(const Handle(GEOM_Field)& theField, const int theID, const int theStamp) { Handle(GEOM_Function) fun = GetFunction(1); if ( !fun.IsNull() ) Standard_MultiplyDefined::Raise( "Reinitialization of GEOM_FieldStep is forbiden" ); fun = AddFunction( GEOM_Field::GetFieldID(), GEOM_Field::FUN_ADD_STEP ); GEOM_IField data( fun ); data.SetField ( theField->GetFunction(1) ); data.SetStepID ( theID ); data.SetStepStamp( theStamp ); // PythonDump to be done by the operation creating this field step } //============================================================================= /*! * GetField */ //============================================================================= Handle(GEOM_FieldStep) GEOM_FieldStep::GetFieldStep(const TDF_Label& theLabel) { Handle(GEOM_BaseObject) base = GEOM_BaseObject::GetObject(theLabel); return Handle(GEOM_FieldStep)::DownCast( base ); } //============================================================================= /*! * Destructor */ //============================================================================= GEOM_FieldStep::~GEOM_FieldStep() { } //======================================================================= //function : GetField //purpose : Returns the Field this GEOM_FieldStep belongs to //======================================================================= Handle(GEOM_Field) GEOM_FieldStep::GetField() { Handle(GEOM_Field) field; Handle(GEOM_Function) fun= GetFunction(1); if ( !fun.IsNull() ) { GEOM_IField data( fun ); Handle(GEOM_Function) fldFun = data.GetField(); if ( !fldFun.IsNull() ) field = GEOM_Field::GetField( fldFun->GetOwnerEntry() ); } return field; } //======================================================================= //function : GetID //purpose : Returns the stamp step id //======================================================================= int GEOM_FieldStep::GetID() { Handle(GEOM_Function) fun= GetFunction(1); if ( !fun.IsNull() ) return GEOM_IField( fun ).GetStepID(); return std::numeric_limits::max(); } //======================================================================= //function : SetStamp //purpose : Sets the stamp of the step //======================================================================= void GEOM_FieldStep::SetStamp(const int stamp) { if ( GetStamp() != stamp ) { // it's stamp modification: field.setStamp(step, stamp) Handle(GEOM_Function) fun = AddFunction( GEOM_Field::GetFieldID(), GEOM_Field::FUN_CHANGE_STEP_STAMP ); GEOM_IField data( fun ); data.SetStepStamp( stamp ); TPythonDump( fun ) << GetField() << ".setStamp( " << GetID() << ", " << stamp << " )"; } } //======================================================================= //function : GetStamp //purpose : Returns the stamp of the step //======================================================================= int GEOM_FieldStep::GetStamp() { // find the last function changing the stamp Handle(GEOM_Function) fun = getFunction( GEOM_Field::FUN_CHANGE_STEP_STAMP, this ); if ( !fun.IsNull() ) return GEOM_IField( fun ).GetStepStamp(); return std::numeric_limits::max(); } //======================================================================= //function : getFunctionToSetValues //purpose : Finds a function to store new values and dumps to Python //======================================================================= Handle(GEOM_Function) GEOM_FieldStep::getFunctionToSetValuesAndDump( const TCollection_AsciiString& valueStr ) { Handle(GEOM_Function) fun = GetLastFunction(); if ( fun->GetType() == GEOM_Field::FUN_ADD_STEP && !fun->HasData( GEOM_IField::STEP_VALUES, GetDataID() )) { // it's creation of the step: field.addStep(step, stamp, values) GEOM_IField data( fun ); TPythonDump( fun ) << this << " = " << GetField() << ".addStep( " << data.GetStepID() << ", " << data.GetStepStamp() << ", " << valueStr << " )"; } else { // it's value modification: field.setValues(step, values) fun = AddFunction( GEOM_Field::GetFieldID(), GEOM_Field::FUN_CHANGE_VALUE ); GEOM_IField data( GetFunction(1) ); TPythonDump( fun ) << GetField() << ".setValues( " << data.GetStepID() << ", " << valueStr << " )"; } return fun; } //======================================================================= //function : SetValues //purpose : Set int or bool values //======================================================================= bool GEOM_FieldStep::SetValues( const Handle(TColStd_HArray1OfInteger)& values ) { Handle(GEOM_Field) field = GetField(); if ( field.IsNull() || values.IsNull() || field->GetArrayLength() != values->Length() ) return false; // fix bool values to be 0 or 1 only if ( field->GetDataType() == 0 ) for ( int i = values->Lower(), nb = values->Upper(); i <= nb; ++i ) values->SetValue( i , bool( values->Value( i ))); Handle(GEOM_Function) fun = getFunctionToSetValuesAndDump( arrayToSting( values )); GEOM_IField data( fun ); data.SetValues( values ); return true; } //======================================================================= //function : SetValues //purpose : Sets double values //======================================================================= bool GEOM_FieldStep::SetValues( const Handle(TColStd_HArray1OfReal)& values ) { Handle(GEOM_Field) field = GetField(); if ( field.IsNull() || values.IsNull() || field->GetArrayLength() != values->Length() ) return false; Handle(GEOM_Function) fun = getFunctionToSetValuesAndDump( arrayToSting( values )); GEOM_IField data( fun ); data.SetValues( values ); return true; } //======================================================================= //function : SetValues //purpose : Sets string values //======================================================================= bool GEOM_FieldStep::SetValues( const Handle(TColStd_HArray1OfExtendedString)& values ) { Handle(GEOM_Field) field = GetField(); if ( field.IsNull() || values.IsNull() || field->GetArrayLength() != values->Length() ) return false; Handle(GEOM_Function) fun = getFunctionToSetValuesAndDump( arrayToSting( values, "'" )); GEOM_IField data( fun ); data.SetValues( values ); return true; } //======================================================================= //function : GetIntValues //purpose : Returns int or bool values //======================================================================= Handle(TColStd_HArray1OfInteger) GEOM_FieldStep::GetIntValues() { Handle(GEOM_Function) fun = getFunction( GEOM_Field::FUN_CHANGE_VALUE, this ); if ( !fun.IsNull() ) return GEOM_IField( fun ).GetIntValues(); return NULL; } //======================================================================= //function : GetDoubleValues //purpose : Returns double values //======================================================================= Handle(TColStd_HArray1OfReal) GEOM_FieldStep::GetDoubleValues() { Handle(GEOM_Function) fun = getFunction( GEOM_Field::FUN_CHANGE_VALUE, this ); if ( !fun.IsNull() ) return GEOM_IField( fun ).GetDoubleValues(); return NULL; } //======================================================================= //function : GetStringValues //purpose : Returns string values //======================================================================= Handle(TColStd_HArray1OfExtendedString) GEOM_FieldStep::GetStringValues() { Handle(GEOM_Function) fun = getFunction( GEOM_Field::FUN_CHANGE_VALUE, this ); if ( !fun.IsNull() ) return GEOM_IField( fun ).GetStringValues(); return NULL; } //======================================================================= //function : GetDataID //purpose : Returns GUID of CAF data array //======================================================================= const Standard_GUID& GEOM_FieldStep::GetDataID() { int dataType = 2; Handle(GEOM_Field) f = GetField(); if ( !f.IsNull() ) dataType = f->GetDataType(); switch ( dataType ) { case 0: // bool case 1: // int return TDataStd_IntegerArray::GetID(); case 2: // double return TDataStd_RealArray::GetID(); default:; // string } return TDataStd_ExtStringArray::GetID(); } IMPLEMENT_STANDARD_HANDLE (GEOM_Field, GEOM_BaseObject ); IMPLEMENT_STANDARD_RTTIEXT(GEOM_Field, GEOM_BaseObject ); IMPLEMENT_STANDARD_HANDLE (GEOM_FieldStep, GEOM_BaseObject ); IMPLEMENT_STANDARD_RTTIEXT(GEOM_FieldStep, GEOM_BaseObject );