1 // Copyright (C) 2007-2024 CEA, EDF, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #include "GEOM_Field.hxx"
25 #include "GEOM_IField.hxx"
26 #include "GEOM_Engine.hxx"
27 #include "GEOM_PythonDump.hxx"
29 #include <Standard_MultiplyDefined.hxx>
30 #include <TDataStd_ChildNodeIterator.hxx>
31 #include <TDataStd_ExtStringArray.hxx>
32 #include <TDataStd_Integer.hxx>
33 #include <TDataStd_IntegerArray.hxx>
34 #include <TDataStd_Real.hxx>
35 #include <TDataStd_RealArray.hxx>
37 #include <TopTools_IndexedMapOfShape.hxx>
39 #include "utilities.h"
47 //================================================================================
49 * \brief Returns a function with a given type OR the 1st function
51 //================================================================================
53 Handle(GEOM_Function) getFunction(int theFunType, GEOM_BaseObject* obj )
55 Handle(GEOM_Function) fun;
56 int nbFuns = obj->GetNbFunctions();
59 fun = obj->GetFunction( nbFuns-- );
60 const int funType = fun->GetType();
61 if ( funType == theFunType )
64 return fun; // function 1
68 //=============================================================================
70 * Constructor: private
72 //=============================================================================
74 GEOM_Field::GEOM_Field(const TDF_Label& theEntry)
75 : GEOM_BaseObject(theEntry), nbSubShapes(-1)
79 //=============================================================================
83 //=============================================================================
85 GEOM_Field::GEOM_Field(const TDF_Label& theEntry, int /*typ*/)
86 : GEOM_BaseObject( theEntry, GEOM_FIELD_OBJTYPE ), nbSubShapes(-1)
90 //================================================================================
92 * \brief Sets the basic data that do not change (except compNames?)
94 //================================================================================
96 void GEOM_Field::Init(const Handle(GEOM_Object)& theShape,
98 const int theDataType,
99 const int theDimension,
100 const Handle(TColStd_HArray1OfExtendedString)& theCompNames)
102 Handle(GEOM_Function) fun = GetFunction(1);
104 Standard_MultiplyDefined::Raise( "Reinitialization of GEOM_Field is forbidden" );
105 fun = AddFunction( GetFieldID(), FUN_ADD_FIELD );
107 GEOM_IField data( fun );
108 data.SetShape ( theShape->GetLastFunction() );
109 data.SetDataType ( theDataType );
110 data.SetDimension ( theDimension );
111 data.SetComponents( theCompNames );
113 TPythonDump py( fun ); // prevent dump of SetName
115 // PythonDump to be done by the operation creating this field
118 //=============================================================================
122 //=============================================================================
124 Handle(GEOM_Field) GEOM_Field::GetField(const TDF_Label& theLabel)
126 Handle(GEOM_BaseObject) base = GEOM_BaseObject::GetObject(theLabel);
127 return Handle(GEOM_Field)::DownCast( base );
130 //=======================================================================
131 //function : GetFieldID
133 //=======================================================================
135 const Standard_GUID& GEOM_Field::GetFieldID()
137 static Standard_GUID anID("FF1BBB01-5252-4df2-980B-3A668264EA16");
141 //=============================================================================
145 //=============================================================================
147 GEOM_Field::~GEOM_Field()
151 //=============================================================================
153 * Returns a shape this GEOM_Field lies on
155 //=============================================================================
157 Handle(GEOM_Object) GEOM_Field::GetShape()
159 Handle(GEOM_Object) shapeObject;
161 Handle(GEOM_Function) fun = GetFunction(1);
164 GEOM_IField data( fun );
165 Handle(GEOM_Function) shapeFun = data.GetShape();
166 if ( !shapeFun.IsNull() )
168 TDF_Label shapeLabel = shapeFun->GetOwnerEntry();
169 shapeObject = GEOM_Object::GetObject( shapeLabel );
176 //=======================================================================
177 //function : GetNbSubShapes
178 //purpose : Returns number of sub-shapes.
179 // Size of data arrays == GetNbSubShapes() * GetComponents()->Extent()
180 //=======================================================================
182 int GEOM_Field::GetNbSubShapes()
184 if ( nbSubShapes < 0 )
185 nbSubShapes = GetNbSubShapes( GetShape(), GetDimension() );
190 //=======================================================================
191 //function : GetNbSubShapes
192 //purpose : Returns number of sub-shapes of given dimension
193 //=======================================================================
195 int GEOM_Field::GetNbSubShapes(const Handle(GEOM_Object)& shObj,
199 if ( shObj.IsNull() ) return nbSubShapes;
201 TopoDS_Shape shape = shObj->GetValue();
202 if (shape.IsNull() ) return nbSubShapes;
210 TopAbs_ShapeEnum type;
212 case 0: type = TopAbs_VERTEX; break;
213 case 1: type = TopAbs_EDGE; break;
214 case 2: type = TopAbs_FACE; break;
215 case 3: type = TopAbs_SOLID; break;
216 default: return nbSubShapes;
218 TopTools_IndexedMapOfShape map;
219 TopExp::MapShapes( shape, type, map );
220 nbSubShapes = map.Extent();
225 //=======================================================================
226 //function : GetNbComponents
227 //purpose : Returns number of components
228 //=======================================================================
230 int GEOM_Field::GetNbComponents()
232 Handle(TColStd_HArray1OfExtendedString) comps = GetComponents();
233 return comps.IsNull() ? 0 : comps->Length();
236 //=======================================================================
237 //function : GetArrayLength
238 //purpose : Returns size of data array == GetNbSubShapes() * GetComponents()->Extent()
239 //=======================================================================
241 int GEOM_Field::GetArrayLength()
243 return GetNbComponents() * GetNbSubShapes();
246 //=======================================================================
247 //function : GetDataType
248 //purpose : Returns a data type of this GEOM_Field
249 //=======================================================================
251 int GEOM_Field::GetDataType()
253 Handle(GEOM_Function) fun = GetFunction(1);
255 return GEOM_IField( fun ).GetDataType();
259 //=======================================================================
260 //function : GetDataTypeString
261 //purpose : Returns one of "Bool","Int","Double","String"
262 //=======================================================================
264 TCollection_AsciiString GEOM_Field::GetDataTypeString(int type)
266 const char* typeNames[] = { "Bool","Int","Double","String" };
267 if ( type < 0 || type > 3 )
269 return typeNames[ type ];
272 //=======================================================================
273 //function : GetDimension
274 //purpose : Returns dimension of the shape the field lies on:
275 // 0 - VERTEX, 1 - EDGE, 2 - FACE, 3 - SOLID, -1 - whole shape
276 //=======================================================================
278 int GEOM_Field::GetDimension()
280 Handle(GEOM_Function) fun = GetFunction(1);
282 return GEOM_IField( fun ).GetDimension();
286 //=======================================================================
287 //function : SetComponents
288 //purpose : Sets names of components
289 //=======================================================================
291 void GEOM_Field::SetComponents( const Handle(TColStd_HArray1OfExtendedString)& compNames )
293 // By spec. modification of components is not required, but just in case...
294 Handle(GEOM_Function) fun = GetLastFunction();
295 if ( fun->GetType() != FUN_ADD_FIELD )
297 fun = AddFunction( GetFieldID(), FUN_CHANGE_COMP_NAMES );
298 //TPythonDump( fun ) << this << ".setComponents( "
300 GEOM_IField data( fun );
301 data.SetComponents( compNames );
304 //=======================================================================
305 //function : GetComponents
306 //purpose : Returns names of components
307 //=======================================================================
309 Handle(TColStd_HArray1OfExtendedString) GEOM_Field::GetComponents()
311 Handle(GEOM_Function) fun = getFunction( FUN_CHANGE_COMP_NAMES, this );
313 return GEOM_IField( fun ).GetComponents();
317 //=======================================================================
318 //function : getFunctionToSetValues
319 //purpose : dump any HArray into a string
320 //=======================================================================
321 template< class HandleArray1 >
322 TCollection_AsciiString arrayToSting( const HandleArray1& ar,
323 const char* quote="")
325 TCollection_AsciiString s;
326 char prefix[] = "[ ";
328 for ( int i = ar->Lower(), nb = ar->Upper(); i <= nb; ++i )
332 s += TCollection_AsciiString( ar->Value( i ));
342 //=======================================================================
343 //function : GetComponentsForPython
344 //purpose : Returns names of components in a python syntax
345 //=======================================================================
347 TCollection_AsciiString GEOM_Field::GetComponentsForPython()
349 return arrayToSting( GetComponents(), "'" );
352 //=======================================================================
354 //purpose : Adds a step
355 //=======================================================================
357 Handle(GEOM_FieldStep) GEOM_Field::AddStep(const int stepID, const int stamp)
359 Handle(GEOM_FieldStep) step = GetStep( stepID );
360 if ( !step.IsNull() )
363 GEOM_Engine* anEngine = GEOM_Engine::GetEngine();
364 if(anEngine == NULL) return NULL;
366 step = Handle(GEOM_FieldStep)::DownCast
367 ( anEngine->AddBaseObject( GEOM_FIELD_STEP_OBJTYPE ));
372 Handle(GEOM_Field) field = GEOM_Field::GetField( GetEntry() );
373 step->Init( field, stepID, stamp );
375 Handle(TDataStd_TreeNode) aRoot, aNode;
376 aRoot = TDataStd_TreeNode::Set( GetEntry(), GetFieldID() );
377 aNode = TDataStd_TreeNode::Set( step->GetEntry(), GetFieldID() );
378 aRoot->Append(aNode);
380 // Dump just in case if step.SetValues() would fail which normally
381 // replaces this dump.
382 // field.addStep(step, stamp, values)
383 TCollection_AsciiString defaultVal( GetDataType() == 3 ? "''" : "0" );
384 TPythonDump( step->GetFunction(1) )
386 << this << ".addStep( "
389 << "[" << defaultVal << "]*" << GetArrayLength() << " )";
394 //=======================================================================
395 //function : RemoveStep
396 //purpose : Removes a step
397 //=======================================================================
399 void GEOM_Field::RemoveStep(const int stepID)
401 Handle(GEOM_FieldStep) step = GetStep( stepID );
405 Handle(TDataStd_TreeNode) aNode =
406 TDataStd_TreeNode::Set( step->GetEntry(), GetFieldID() );
407 aNode->Remove(); // Removes this tree node attribute from its father
409 // Dump of removed objects is not produced anayway
410 //Handle(GEOM_Function) fun = AddFunction( GetFieldID(), FUN_REMOVE_STEP );
411 //TPythonDump( fun ) << this << ".removeStep( " << stepID << " )";
413 GEOM_Engine* anEngine = GEOM_Engine::GetEngine();
415 anEngine->RemoveObject( step );
418 //=======================================================================
420 //purpose : Returns a step
421 //=======================================================================
423 Handle(GEOM_FieldStep) GEOM_Field::GetStep(const int stepID)
425 Handle(GEOM_FieldStep) step;
427 Handle(TDataStd_TreeNode) aRoot, aNode;
428 if ( !GetEntry().FindAttribute( GetFieldID(), aRoot ))
431 TDataStd_ChildNodeIterator anIter (aRoot);
432 for (; anIter.More(); anIter.Next())
434 aNode = anIter.Value();
435 step = GEOM_FieldStep::GetFieldStep( aNode->Label() );
436 if ( !step.IsNull() && step->GetID() == stepID )
442 //=======================================================================
443 //function : GetSteps
444 //purpose : Returns all steps
445 //=======================================================================
447 std::list< Handle(GEOM_FieldStep)> GEOM_Field::GetSteps()
449 std::list< Handle(GEOM_FieldStep) > stepList;
451 Handle(TDataStd_TreeNode) aRoot, aNode;
452 if ( !GetEntry().FindAttribute( GetFieldID(), aRoot ))
455 Handle(GEOM_FieldStep) step;
456 TDataStd_ChildNodeIterator anIter (aRoot);
457 for (; anIter.More(); anIter.Next())
459 aNode = anIter.Value();
460 step = GEOM_FieldStep::GetFieldStep( aNode->Label() );
461 if ( !step.IsNull() )
462 stepList.push_back( step );
467 //=============================================================================
469 * Constructor: private
471 //=============================================================================
473 GEOM_FieldStep::GEOM_FieldStep(const TDF_Label& theEntry)
474 : GEOM_BaseObject(theEntry)
478 //=============================================================================
480 * Constructor: public
482 //=============================================================================
484 GEOM_FieldStep::GEOM_FieldStep(const TDF_Label& theLabel, int /*type*/ )
485 : GEOM_BaseObject( theLabel, GEOM_FIELD_STEP_OBJTYPE )
489 //================================================================================
491 * \brief Sets the basic data
493 //================================================================================
495 void GEOM_FieldStep::Init(const Handle(GEOM_Field)& theField,
499 Handle(GEOM_Function) fun = GetFunction(1);
501 Standard_MultiplyDefined::Raise( "Reinitialization of GEOM_FieldStep is forbidden" );
502 fun = AddFunction( GEOM_Field::GetFieldID(), GEOM_Field::FUN_ADD_STEP );
504 GEOM_IField data( fun );
505 data.SetField ( theField->GetFunction(1) );
506 data.SetStepID ( theID );
507 data.SetStepStamp( theStamp );
508 // PythonDump to be done by the operation creating this field step
511 //=============================================================================
515 //=============================================================================
517 Handle(GEOM_FieldStep) GEOM_FieldStep::GetFieldStep(const TDF_Label& theLabel)
519 Handle(GEOM_BaseObject) base = GEOM_BaseObject::GetObject(theLabel);
520 return Handle(GEOM_FieldStep)::DownCast( base );
523 //=============================================================================
527 //=============================================================================
529 GEOM_FieldStep::~GEOM_FieldStep()
533 //=======================================================================
534 //function : GetField
535 //purpose : Returns the Field this GEOM_FieldStep belongs to
536 //=======================================================================
538 Handle(GEOM_Field) GEOM_FieldStep::GetField()
540 Handle(GEOM_Field) field;
542 Handle(GEOM_Function) fun= GetFunction(1);
545 GEOM_IField data( fun );
546 Handle(GEOM_Function) fldFun = data.GetField();
547 if ( !fldFun.IsNull() )
548 field = GEOM_Field::GetField( fldFun->GetOwnerEntry() );
553 //=======================================================================
555 //purpose : Returns the stamp step id
556 //=======================================================================
558 int GEOM_FieldStep::GetID()
560 Handle(GEOM_Function) fun= GetFunction(1);
562 return GEOM_IField( fun ).GetStepID();
563 return std::numeric_limits<int>::max();
566 //=======================================================================
567 //function : SetStamp
568 //purpose : Sets the stamp of the step
569 //=======================================================================
571 void GEOM_FieldStep::SetStamp(const int stamp)
573 if ( GetStamp() != stamp )
575 // it's stamp modification: field.setStamp(step, stamp)
576 Handle(GEOM_Function) fun =
577 AddFunction( GEOM_Field::GetFieldID(), GEOM_Field::FUN_CHANGE_STEP_STAMP );
579 GEOM_IField data( fun );
580 data.SetStepStamp( stamp );
582 TPythonDump( fun ) <<
583 GetField() << ".setStamp( " << GetID() << ", " << stamp << " )";
587 //=======================================================================
588 //function : GetStamp
589 //purpose : Returns the stamp of the step
590 //=======================================================================
592 int GEOM_FieldStep::GetStamp()
594 // find the last function changing the stamp
595 Handle(GEOM_Function) fun = getFunction( GEOM_Field::FUN_CHANGE_STEP_STAMP, this );
597 return GEOM_IField( fun ).GetStepStamp();
598 return std::numeric_limits<int>::max();
601 //=======================================================================
602 //function : getFunctionToSetValues
603 //purpose : Finds a function to store new values and dumps to Python
604 //=======================================================================
606 Handle(GEOM_Function)
607 GEOM_FieldStep::getFunctionToSetValuesAndDump( const TCollection_AsciiString& valueStr )
609 Handle(GEOM_Function) fun = GetLastFunction();
610 if ( fun->GetType() == GEOM_Field::FUN_ADD_STEP &&
611 !fun->HasData( GEOM_IField::STEP_VALUES, GetDataID() ))
613 // it's creation of the step: field.addStep(step, stamp, values)
614 GEOM_IField data( fun );
615 TPythonDump( fun ) << this << " = " << GetField() << ".addStep( " <<
616 data.GetStepID() << ", " << data.GetStepStamp() << ", " << valueStr << " )";
620 // it's value modification: field.setValues(step, values)
621 fun = AddFunction( GEOM_Field::GetFieldID(), GEOM_Field::FUN_CHANGE_VALUE );
622 GEOM_IField data( GetFunction(1) );
623 TPythonDump( fun ) << GetField() << ".setValues( " <<
624 data.GetStepID() << ", " << valueStr << " )";
629 //=======================================================================
630 //function : SetValues
631 //purpose : Set int or bool values
632 //=======================================================================
634 bool GEOM_FieldStep::SetValues( const Handle(TColStd_HArray1OfInteger)& values )
636 Handle(GEOM_Field) field = GetField();
637 if ( field.IsNull() ||
639 field->GetArrayLength() != values->Length() )
642 // fix bool values to be 0 or 1 only
643 if ( field->GetDataType() == 0 )
644 for ( int i = values->Lower(), nb = values->Upper(); i <= nb; ++i )
645 values->SetValue( i , bool( values->Value( i )));
647 Handle(GEOM_Function) fun =
648 getFunctionToSetValuesAndDump( arrayToSting( values ));
650 GEOM_IField data( fun );
651 data.SetValues( values );
655 //=======================================================================
656 //function : SetValues
657 //purpose : Sets double values
658 //=======================================================================
660 bool GEOM_FieldStep::SetValues( const Handle(TColStd_HArray1OfReal)& values )
662 Handle(GEOM_Field) field = GetField();
663 if ( field.IsNull() ||
665 field->GetArrayLength() != values->Length() )
668 Handle(GEOM_Function) fun =
669 getFunctionToSetValuesAndDump( arrayToSting( values ));
671 GEOM_IField data( fun );
672 data.SetValues( values );
676 //=======================================================================
677 //function : SetValues
678 //purpose : Sets string values
679 //=======================================================================
681 bool GEOM_FieldStep::SetValues( const Handle(TColStd_HArray1OfExtendedString)& values )
683 Handle(GEOM_Field) field = GetField();
684 if ( field.IsNull() ||
686 field->GetArrayLength() != values->Length() )
689 Handle(GEOM_Function) fun =
690 getFunctionToSetValuesAndDump( arrayToSting( values, "'" ));
692 GEOM_IField data( fun );
693 data.SetValues( values );
697 //=======================================================================
698 //function : GetIntValues
699 //purpose : Returns int or bool values
700 //=======================================================================
702 Handle(TColStd_HArray1OfInteger) GEOM_FieldStep::GetIntValues()
704 Handle(GEOM_Function) fun = getFunction( GEOM_Field::FUN_CHANGE_VALUE, this );
706 return GEOM_IField( fun ).GetIntValues();
710 //=======================================================================
711 //function : GetDoubleValues
712 //purpose : Returns double values
713 //=======================================================================
715 Handle(TColStd_HArray1OfReal) GEOM_FieldStep::GetDoubleValues()
717 Handle(GEOM_Function) fun = getFunction( GEOM_Field::FUN_CHANGE_VALUE, this );
719 return GEOM_IField( fun ).GetDoubleValues();
723 //=======================================================================
724 //function : GetStringValues
725 //purpose : Returns string values
726 //=======================================================================
728 Handle(TColStd_HArray1OfExtendedString) GEOM_FieldStep::GetStringValues()
730 Handle(GEOM_Function) fun = getFunction( GEOM_Field::FUN_CHANGE_VALUE, this );
732 return GEOM_IField( fun ).GetStringValues();
736 //=======================================================================
737 //function : GetDataID
738 //purpose : Returns GUID of CAF data array
739 //=======================================================================
741 const Standard_GUID& GEOM_FieldStep::GetDataID()
744 Handle(GEOM_Field) f = GetField();
746 dataType = f->GetDataType();
748 switch ( dataType ) {
751 return TDataStd_IntegerArray::GetID();
753 return TDataStd_RealArray::GetID();
756 return TDataStd_ExtStringArray::GetID();
759 IMPLEMENT_STANDARD_RTTIEXT(GEOM_Field, GEOM_BaseObject )
760 IMPLEMENT_STANDARD_RTTIEXT(GEOM_FieldStep, GEOM_BaseObject )