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 // SMESH OBJECT : interactive object for SMESH visualization
24 // File : SMESH_DeviceActor.cxx
28 #include "SMESH_DeviceActor.h"
29 #include "SMESH_ScalarBarActor.h"
30 #include "SMESH_ExtractGeometry.h"
31 #include "SMESH_ControlsDef.hxx"
32 #include "SMESH_ActorUtils.h"
33 #include "SMESH_FaceOrientationFilter.h"
34 //#include "VTKViewer_CellLocationsArray.h"
35 #include "VTKViewer_PolyDataMapper.h"
37 #include <VTKViewer_Transform.h>
38 #include <VTKViewer_TransformFilter.h>
39 #include <VTKViewer_ExtractUnstructuredGrid.h>
40 #include <VTKViewer_Actor.h>
43 #include <vtkObjectFactory.h>
44 #include <vtkShrinkFilter.h>
45 #include <vtkShrinkPolyData.h>
47 #include <vtkProperty.h>
48 #include <vtkPolyData.h>
49 #include <vtkMergeFilter.h>
50 #include <vtkPolyDataMapper.h>
51 #include <vtkUnstructuredGrid.h>
53 #include <vtkLookupTable.h>
54 #include <vtkDoubleArray.h>
55 #include <vtkCellData.h>
58 #include <vtkIdList.h>
59 #include <vtkCellArray.h>
60 #include <vtkUnsignedCharArray.h>
62 #include <vtkImplicitBoolean.h>
63 #include <vtkPassThrough.h>
65 #include <vtkRenderer.h>
67 #include <vtkPlaneCollection.h>
69 #include "utilities.h"
75 vtkStandardNewMacro(SMESH_DeviceActor)
81 MESSAGE("SMESH_DeviceActor - "<<this);
83 myIsShrinkable = false;
85 myIsHighlited = false;
87 myRepresentation = SMESH_DeviceActor::EReperesent(-1);
89 myProperty = vtkProperty::New();
90 myMapper = VTKViewer_PolyDataMapper::New();
91 myPlaneCollection = vtkPlaneCollection::New();
93 VTKViewer_Actor::GetDefaultPolygonOffsetParameters(myPolygonOffsetFactor,
94 myPolygonOffsetUnits);
96 myMapper->UseLookupTableScalarRangeOn();
97 myMapper->SetColorModeToMapScalars();
99 myShrinkFilter = vtkShrinkFilter::New();
101 myStoreClippingMapping = false;
103 myExtractGeometry = SMESH_ExtractGeometry::New();
104 myExtractGeometry->SetReleaseDataFlag(true);
105 myIsImplicitFunctionUsed = false;
107 myExtractUnstructuredGrid = VTKViewer_ExtractUnstructuredGrid::New();
109 myMergeFilter = vtkMergeFilter::New();
111 myGeomFilter = VTKViewer_GeometryFilter::New();
113 myTransformFilter = VTKViewer_TransformFilter::New();
115 for(int i = 0; i < 6; i++)
116 myPassFilter.push_back(vtkPassThrough::New());
118 // Orientation of faces
119 myIsFacesOriented = false;
121 double anRGB[3] = { 1, 1, 1 };
122 SMESH::GetColor( "SMESH", "orientation_color", anRGB[0], anRGB[1], anRGB[2], QColor( 255, 255, 255 ) );
124 myFaceOrientationFilter = SMESH_FaceOrientationFilter::New();
126 myFaceOrientationDataMapper = vtkPolyDataMapper::New();
127 myFaceOrientationDataMapper->SetInputConnection(myFaceOrientationFilter->GetOutputPort());
129 myFaceOrientation = vtkActor::New();
130 myFaceOrientation->SetMapper(myFaceOrientationDataMapper);
131 myFaceOrientation->GetProperty()->SetColor(anRGB[0], anRGB[1], anRGB[2]);
136 ::~SMESH_DeviceActor()
138 MESSAGE("~SMESH_DeviceActor - "<<this);
141 // myPlaneCollection->Delete(); -- it is vtkSmartPointer
142 myProperty->Delete();
144 myExtractGeometry->Delete();
146 myMergeFilter->Delete();
147 myExtractUnstructuredGrid->Delete();
149 // Orientation of faces
150 myFaceOrientationFilter->Delete();
151 myFaceOrientationDataMapper->RemoveAllInputs();
152 myFaceOrientationDataMapper->Delete();
153 myFaceOrientation->Delete();
155 myGeomFilter->Delete();
157 myTransformFilter->Delete();
159 for(size_t i = 0, iEnd = myPassFilter.size(); i < iEnd; i++)
160 myPassFilter[i]->Delete();
162 myShrinkFilter->Delete();
168 ::SetStoreGemetryMapping(bool theStoreMapping)
170 myGeomFilter->SetStoreMapping(theStoreMapping);
171 // for optimization, switch the mapping explicitly in each filter/algorithm
172 //SetStoreClippingMapping(theStoreMapping);
178 ::SetStoreClippingMapping(bool theStoreMapping)
180 myStoreClippingMapping = theStoreMapping;
181 myExtractGeometry->SetStoreMapping(theStoreMapping && myIsImplicitFunctionUsed);
183 // Mapping in myExtractUnstructuredGrid and myGeomFilter is ON in the pickable DeviceActor only.
184 // To show labels, the mapping is computed explicitly via myExtractUnstructuredGrid->BuildOut2InMap();
185 //SetStoreIDMapping(theStoreMapping);
191 ::SetStoreIDMapping(bool theStoreMapping)
193 myExtractUnstructuredGrid->SetStoreMapping(theStoreMapping);
199 ::Init(TVisualObjPtr theVisualObj,
200 vtkImplicitBoolean* theImplicitBoolean)
202 myVisualObj = theVisualObj;
203 myExtractGeometry->SetImplicitFunction(theImplicitBoolean);
204 SetUnstructuredGrid(myVisualObj->GetUnstructuredGrid());
209 ::SetImplicitFunctionUsed(bool theIsImplicitFunctionUsed)
212 if(theIsImplicitFunctionUsed)
213 myPassFilter[ anId ]->SetInputConnection( myExtractGeometry->GetOutputPort() );
215 myPassFilter[ anId ]->SetInputConnection( myMergeFilter->GetOutputPort() );
217 myIsImplicitFunctionUsed = theIsImplicitFunctionUsed;
218 SetStoreClippingMapping(myStoreClippingMapping);
224 ::SetUnstructuredGrid(vtkUnstructuredGrid* theGrid)
226 myExtractUnstructuredGrid->SetInputData(theGrid);
230 myIsShrinkable = true;
232 myMergeFilter->SetGeometryConnection(myExtractUnstructuredGrid->GetOutputPort());
234 //Pass diameters of the balls
235 if(myMapper->GetBallEnabled()) {
236 myMergeFilter->SetScalarsConnection(myExtractUnstructuredGrid->GetOutputPort());
239 myExtractGeometry->SetInputConnection(myMergeFilter->GetOutputPort());
242 SetImplicitFunctionUsed(myIsImplicitFunctionUsed);
243 myPassFilter[ anId + 1]->SetInputConnection( myPassFilter[ anId ]->GetOutputPort() );
246 myTransformFilter->SetInputConnection( myPassFilter[ anId ]->GetOutputPort() );
249 myPassFilter[ anId ]->SetInputConnection( myTransformFilter->GetOutputPort() );
250 myPassFilter[ anId + 1 ]->SetInputConnection( myPassFilter[ anId ]->GetOutputPort() );
253 myGeomFilter->SetInputConnection( myPassFilter[ anId ]->GetOutputPort() );
256 myPassFilter[ anId ]->SetInputConnection( myGeomFilter->GetOutputPort() );
257 myPassFilter[ anId + 1 ]->SetInputConnection( myPassFilter[ anId ]->GetOutputPort() );
260 myMapper->SetInputConnection( myPassFilter[ anId ]->GetOutputPort() );
261 if( myPlaneCollection->GetNumberOfItems() )
262 myMapper->SetClippingPlanes( myPlaneCollection );
264 vtkLODActor::SetMapper( myMapper );
271 ::SetPlaneCollection( vtkPlaneCollection* theCollection )
273 myPlaneCollection = theCollection;
276 VTKViewer_ExtractUnstructuredGrid*
278 ::GetExtractUnstructuredGrid()
280 return myExtractUnstructuredGrid;
283 #include "SMDS_Mesh.hxx"
287 ::GetUnstructuredGrid()
289 myExtractUnstructuredGrid->Update();
290 return myExtractUnstructuredGrid->GetOutput();
296 ::SetControlMode(SMESH::Controls::FunctorPtr theFunctor,
297 SMESH_ScalarBarActor* theScalarBarActor,
298 vtkLookupTable* theLookupTable)
300 bool anIsInitialized = theFunctor != NULL;
302 vtkUnstructuredGrid* aDataSet = vtkUnstructuredGrid::New();
304 // SetStoreIDMapping(true);
305 myExtractUnstructuredGrid->Update();
306 vtkUnstructuredGrid* aGrid = myExtractUnstructuredGrid->GetOutput();
308 aDataSet->ShallowCopy(aGrid);
310 vtkDoubleArray *aScalars = vtkDoubleArray::New();
311 vtkIdType aNbCells = aGrid->GetNumberOfCells();
312 aScalars->SetNumberOfComponents(1);
313 aScalars->SetNumberOfTuples(aNbCells);
314 double* range = 0;// = aScalars->GetRange();
316 myVisualObj->UpdateFunctor(theFunctor);
318 using namespace SMESH::Controls;
319 if(NumericalFunctor* aNumericalFunctor = dynamic_cast<NumericalFunctor*>(theFunctor.get()))
321 myExtractUnstructuredGrid->BuildOut2InMap();
322 for(vtkIdType i = 0; i < aNbCells; i++)
324 vtkIdType anId = myExtractUnstructuredGrid->GetInputId(i);
325 vtkIdType anObjId = myVisualObj->GetElemObjId(anId);
326 double aValue = aNumericalFunctor->GetValue(anObjId);
327 aScalars->SetValue(i,aValue);
329 range = aScalars->GetRange();
330 if ( range[1] - range[0] < ( qMax(qAbs(range[0]),qAbs(range[1])) + 1e-100 ) * 1e-6 )
333 for(vtkIdType i = 0; i < aNbCells; i++)
334 aScalars->SetValue(i,range[0]);
337 else if(Predicate* aPredicate = dynamic_cast<Predicate*>(theFunctor.get()))
339 myExtractUnstructuredGrid->BuildOut2InMap();
340 for(vtkIdType i = 0; i < aNbCells; i++)
342 vtkIdType anId = myExtractUnstructuredGrid->GetInputId(i);
343 vtkIdType anObjId = myVisualObj->GetElemObjId(anId);
344 bool aValue = aPredicate->IsSatisfy(anObjId);
345 aScalars->SetValue(i,aValue);
347 range = aScalars->GetRange();
350 aDataSet->GetCellData()->SetScalars(aScalars);
353 theLookupTable->SetRange( range );
354 theLookupTable->SetNumberOfTableValues(theScalarBarActor->GetMaximumNumberOfColors());
355 theLookupTable->Build();
357 myMergeFilter->SetScalarsData(aDataSet);
360 GetMapper()->SetScalarVisibility(anIsInitialized);
361 theScalarBarActor->SetVisibility(anIsInitialized);
366 ::SetExtControlMode(SMESH::Controls::FunctorPtr theFunctor,
367 SMESH_ScalarBarActor* theScalarBarActor,
368 vtkLookupTable* theLookupTable)
370 bool anIsInitialized = theFunctor != NULL;
371 myExtractUnstructuredGrid->ClearRegisteredCells();
372 myExtractUnstructuredGrid->ClearRegisteredCellsWithType();
373 myExtractUnstructuredGrid->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::ePassAll);
374 myVisualObj->UpdateFunctor(theFunctor);
376 using namespace SMESH::Controls;
377 if (anIsInitialized){
378 if (Length2D* aLength2D = dynamic_cast<Length2D*>(theFunctor.get())){
379 SMESH::Controls::Length2D::TValues aValues;
381 aLength2D->GetValues(aValues);
382 vtkUnstructuredGrid* aDataSet = vtkUnstructuredGrid::New();
383 vtkUnstructuredGrid* aGrid = myVisualObj->GetUnstructuredGrid();
385 aDataSet->SetPoints(aGrid->GetPoints());
387 vtkIdType aNbCells = aValues.size();
389 vtkDoubleArray *aScalars = vtkDoubleArray::New();
390 aScalars->SetNumberOfComponents(1);
391 aScalars->SetNumberOfTuples(aNbCells);
393 vtkIdType aCellsSize = 3*aNbCells;
394 vtkCellArray* aConnectivity = vtkCellArray::New();
395 aConnectivity->Allocate( aCellsSize, 0 );
397 vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
398 aCellTypesArray->SetNumberOfComponents( 1 );
399 aCellTypesArray->Allocate( aNbCells * aCellTypesArray->GetNumberOfComponents() );
401 vtkIdList *anIdList = vtkIdList::New();
402 anIdList->SetNumberOfIds(2);
404 Length2D::TValues::const_iterator anIter = aValues.begin();
406 for(; anIter != aValues.end(); anIter++){
407 const Length2D::Value& aValue = *anIter;
408 vtkIdType aNode[2] = {
409 myVisualObj->GetNodeVTKId(aValue.myPntId[0]),
410 myVisualObj->GetNodeVTKId(aValue.myPntId[1])
412 if(aNode[0] >= 0 && aNode[1] >= 0){
413 anIdList->SetId( 0, aNode[0] );
414 anIdList->SetId( 1, aNode[1] );
415 aConnectivity->InsertNextCell( anIdList );
416 aCellTypesArray->InsertNextValue( VTK_LINE );
417 aScalars->SetValue(aNbCells,aValue.myLength);
421 aCellTypesArray->SetNumberOfTuples( aNbCells );
422 aScalars->SetNumberOfTuples( aNbCells );
424 vtkIdTypeArray* aCellLocationsArray = vtkIdTypeArray::New();
425 aCellLocationsArray->SetNumberOfComponents( 1 );
426 aCellLocationsArray->SetNumberOfTuples( aNbCells );
428 aConnectivity->InitTraversal();
429 vtkIdType const *pts(nullptr);
430 for( vtkIdType idType = 0, npts; aConnectivity->GetNextCell( npts, pts ); idType++ )
431 aCellLocationsArray->SetValue( idType, aConnectivity->GetTraversalLocation( npts ) );
433 aDataSet->SetCells( aCellTypesArray, aCellLocationsArray, aConnectivity );
434 SetUnstructuredGrid(aDataSet);
436 aDataSet->GetCellData()->SetScalars(aScalars);
439 theLookupTable->SetRange(aScalars->GetRange());
440 theLookupTable->Build();
442 myMergeFilter->SetScalarsData(aDataSet);
445 else if (MultiConnection2D* aMultiConnection2D = dynamic_cast<MultiConnection2D*>(theFunctor.get())){
446 SMESH::Controls::MultiConnection2D::MValues aValues;
448 aMultiConnection2D->GetValues(aValues);
449 vtkUnstructuredGrid* aDataSet = vtkUnstructuredGrid::New();
450 vtkUnstructuredGrid* aGrid = myVisualObj->GetUnstructuredGrid();
451 aDataSet->SetPoints(aGrid->GetPoints());
453 vtkIdType aNbCells = aValues.size();
454 vtkDoubleArray *aScalars = vtkDoubleArray::New();
455 aScalars->SetNumberOfComponents(1);
456 aScalars->SetNumberOfTuples(aNbCells);
458 vtkIdType aCellsSize = 3*aNbCells;
459 vtkCellArray* aConnectivity = vtkCellArray::New();
460 aConnectivity->Allocate( aCellsSize, 0 );
462 vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
463 aCellTypesArray->SetNumberOfComponents( 1 );
464 aCellTypesArray->Allocate( aNbCells * aCellTypesArray->GetNumberOfComponents() );
466 vtkIdList *anIdList = vtkIdList::New();
467 anIdList->SetNumberOfIds(2);
469 MultiConnection2D::MValues::const_iterator anIter = aValues.begin();
471 for(; anIter != aValues.end(); anIter++){
472 const MultiConnection2D::Value& aValue = (*anIter).first;
473 vtkIdType aNode[2] = {
474 myVisualObj->GetNodeVTKId(aValue.myPntId[0]),
475 myVisualObj->GetNodeVTKId(aValue.myPntId[1])
477 if(aNode[0] >= 0 && aNode[1] >= 0){
478 anIdList->SetId( 0, aNode[0] );
479 anIdList->SetId( 1, aNode[1] );
480 aConnectivity->InsertNextCell( anIdList );
481 aCellTypesArray->InsertNextValue( VTK_LINE );
482 aScalars->SetValue( aNbCells,(*anIter).second);
486 aCellTypesArray->SetNumberOfTuples( aNbCells );
487 aScalars->SetNumberOfTuples( aNbCells );
489 vtkIdTypeArray* aCellLocationsArray = vtkIdTypeArray::New();
490 aCellLocationsArray->SetNumberOfComponents( 1 );
491 aCellLocationsArray->SetNumberOfTuples( aNbCells );
493 aConnectivity->InitTraversal();
494 vtkIdType const *pts(nullptr);
495 for( vtkIdType idType = 0, npts; aConnectivity->GetNextCell( npts, pts ); idType++ )
496 aCellLocationsArray->SetValue( idType, aConnectivity->GetTraversalLocation( npts ) );
498 aDataSet->SetCells( aCellTypesArray, aCellLocationsArray,aConnectivity );
499 SetUnstructuredGrid(aDataSet);
501 aDataSet->GetCellData()->SetScalars(aScalars);
504 theLookupTable->SetRange(aScalars->GetRange());
505 theLookupTable->Build();
507 myMergeFilter->SetScalarsData(aDataSet);
510 else if (Warping3D* aWarping3D = dynamic_cast<Warping3D*>(theFunctor.get())){
512 SMESH::Controls::Warping3D::WValues aValues;
514 aWarping3D->GetValues(aValues);
515 vtkUnstructuredGrid* aDataSet = vtkUnstructuredGrid::New();
516 vtkUnstructuredGrid* aGrid = myVisualObj->GetUnstructuredGrid();
518 aDataSet->SetPoints(aGrid->GetPoints());
520 vtkIdType aNbCells = aValues.size();
522 vtkDoubleArray* aScalars = vtkDoubleArray::New();
523 aScalars->SetNumberOfComponents(1);
524 aScalars->SetNumberOfTuples(aNbCells);
526 vtkIdType aCellsSize = 3 * aNbCells;
527 vtkCellArray* aConnectivity = vtkCellArray::New();
528 aConnectivity->Allocate(aCellsSize, 0);
530 vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
531 aCellTypesArray->SetNumberOfComponents(1);
532 aCellTypesArray->Allocate(aNbCells* aCellTypesArray->GetNumberOfComponents());
534 Warping3D::WValues::const_iterator anIter = aValues.begin();
536 for (; anIter != aValues.end(); anIter++) {
538 const Warping3D::Value& aValue = *anIter;
539 vtkIdList* anIdList = vtkIdList::New();
540 anIdList->SetNumberOfIds(aValue.myPntIds.size());
542 for (int i = 0; i < aValue.myPntIds.size(); ++i)
544 int aVTKId = myVisualObj->GetNodeVTKId(aValue.myPntIds[i]);
550 anIdList->SetId(i, aVTKId);
554 aConnectivity->InsertNextCell(anIdList);
555 aCellTypesArray->InsertNextValue(VTK_POLYGON);
556 aScalars->SetValue(aNbCells, aValue.myWarp);
560 aCellTypesArray->SetNumberOfTuples(aNbCells);
561 aScalars->SetNumberOfTuples(aNbCells);
563 vtkIdTypeArray* aCellLocationsArray = vtkIdTypeArray::New();
564 aCellLocationsArray->SetNumberOfComponents(1);
565 aCellLocationsArray->SetNumberOfTuples(aNbCells);
567 aConnectivity->InitTraversal();
568 vtkIdType const* pts(nullptr);
569 for (vtkIdType idType = 0, npts; aConnectivity->GetNextCell(npts, pts); idType++)
570 aCellLocationsArray->SetValue(idType, aConnectivity->GetTraversalLocation(npts));
572 aDataSet->SetCells(aCellTypesArray, aCellLocationsArray, aConnectivity);
573 SetUnstructuredGrid(aDataSet);
575 aDataSet->GetCellData()->SetScalars(aScalars);
578 theLookupTable->SetRange(aScalars->GetRange());
579 theLookupTable->Build();
581 myMergeFilter->SetScalarsData(aDataSet);
585 GetMapper()->SetScalarVisibility(anIsInitialized);
586 theScalarBarActor->SetVisibility(anIsInitialized);
591 ::SetExtControlMode(SMESH::Controls::FunctorPtr theFunctor)
593 myExtractUnstructuredGrid->ClearRegisteredCells();
594 myExtractUnstructuredGrid->ClearRegisteredCellsWithType();
595 myExtractUnstructuredGrid->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::ePassAll);
596 myVisualObj->UpdateFunctor(theFunctor);
598 using namespace SMESH::Controls;
599 Predicate* aPredicate = 0;
600 if (( aPredicate = dynamic_cast<FreeBorders *>(theFunctor.get())) ||
601 ( aPredicate = dynamic_cast<FreeFaces *>(theFunctor.get())) ||
602 ( aPredicate = dynamic_cast<BareBorderVolume *>(theFunctor.get())) ||
603 ( aPredicate = dynamic_cast<BareBorderFace *>(theFunctor.get())) ||
604 ( aPredicate = dynamic_cast<OverConstrainedVolume*>(theFunctor.get())) ||
605 ( aPredicate = dynamic_cast<CoincidentElements1D *>(theFunctor.get())) ||
606 ( aPredicate = dynamic_cast<CoincidentElements2D *>(theFunctor.get())) ||
607 ( aPredicate = dynamic_cast<CoincidentElements3D *>(theFunctor.get())) ||
608 ( aPredicate = dynamic_cast<OverConstrainedFace *>(theFunctor.get())))
610 myExtractUnstructuredGrid->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding);
611 vtkUnstructuredGrid* aGrid = myVisualObj->GetUnstructuredGrid();
612 vtkIdType aNbCells = aGrid->GetNumberOfCells();
613 for( vtkIdType i = 0; i < aNbCells; i++ ){
614 vtkIdType anObjId = myVisualObj->GetElemObjId(i);
615 if(aPredicate->IsSatisfy(anObjId))
616 myExtractUnstructuredGrid->RegisterCell(i);
618 if(!myExtractUnstructuredGrid->IsCellsRegistered())
619 myExtractUnstructuredGrid->RegisterCell(-1);
620 SetUnstructuredGrid(myVisualObj->GetUnstructuredGrid());
622 else if(FreeEdges* aFreeEdges = dynamic_cast<FreeEdges*>(theFunctor.get()))
624 SMESH::Controls::FreeEdges::TBorders aBorders;
625 aFreeEdges->GetBoreders(aBorders);
626 vtkUnstructuredGrid* aDataSet = vtkUnstructuredGrid::New();
627 vtkUnstructuredGrid* aGrid = myVisualObj->GetUnstructuredGrid();
628 aDataSet->SetPoints(aGrid->GetPoints());
630 vtkIdType aNbCells = aBorders.size();
631 vtkIdType aCellsSize = 3*aNbCells;
632 vtkCellArray* aConnectivity = vtkCellArray::New();
633 aConnectivity->Allocate( aCellsSize, 0 );
635 vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
636 aCellTypesArray->SetNumberOfComponents( 1 );
637 aCellTypesArray->Allocate( aNbCells * aCellTypesArray->GetNumberOfComponents() );
639 vtkIdList *anIdList = vtkIdList::New();
640 anIdList->SetNumberOfIds(2);
642 FreeEdges::TBorders::const_iterator anIter = aBorders.begin();
643 for(; anIter != aBorders.end(); anIter++){
644 const FreeEdges::Border& aBorder = *anIter;
645 vtkIdType aNode[2] = {
646 myVisualObj->GetNodeVTKId(aBorder.myPntId[0]),
647 myVisualObj->GetNodeVTKId(aBorder.myPntId[1])
649 //cout<<"aNode = "<<aBorder.myPntId[0]<<"; "<<aBorder.myPntId[1]<<endl;
650 if(aNode[0] >= 0 && aNode[1] >= 0){
651 anIdList->SetId( 0, aNode[0] );
652 anIdList->SetId( 1, aNode[1] );
653 aConnectivity->InsertNextCell( anIdList );
654 aCellTypesArray->InsertNextValue( VTK_LINE );
658 vtkIdTypeArray* aCellLocationsArray = vtkIdTypeArray::New();
659 aCellLocationsArray->SetNumberOfComponents( 1 );
660 aCellLocationsArray->SetNumberOfTuples( aNbCells );
662 aConnectivity->InitTraversal();
663 vtkIdType const *pts(nullptr);
664 for( vtkIdType idType = 0, npts; aConnectivity->GetNextCell( npts, pts ); idType++ )
665 aCellLocationsArray->SetValue( idType, aConnectivity->GetTraversalLocation( npts ) );
667 aDataSet->SetCells( aCellTypesArray, aCellLocationsArray,aConnectivity );
669 SetUnstructuredGrid(aDataSet);
672 else if (( aPredicate = dynamic_cast<FreeNodes *>(theFunctor.get())) ||
673 ( aPredicate = dynamic_cast<CoincidentNodes*>(theFunctor.get())))
675 myExtractUnstructuredGrid->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding);
676 vtkIdType aNbNodes = FromSmIdType<vtkIdType>(myVisualObj->GetNbEntities(SMDSAbs_Node));
677 for( vtkIdType i = 0; i < aNbNodes; i++ ){
678 vtkIdType anObjId = myVisualObj->GetNodeObjId(i);
679 if(aPredicate->IsSatisfy(anObjId))
680 myExtractUnstructuredGrid->RegisterCell(i);
682 if(!myExtractUnstructuredGrid->IsCellsRegistered())
683 myExtractUnstructuredGrid->RegisterCell(-1);
684 SetUnstructuredGrid(myVisualObj->GetUnstructuredGrid());
695 // cout << "DA " << this
696 // << " GF " << myGeomFilter;
697 // if ( this->Property )
698 // cout << " P " << this->Property->GetMTime();
699 // if ( this->BackfaceProperty != NULL )
700 // cout << " BP " << BackfaceProperty->GetMTime();
701 // if ( this->Texture != NULL )
702 // cout << " T " << this->Texture->GetMTime();
703 // cout << " U " << this->GetUserTransformMatrixMTime()
704 // << " M " << this->MTime.GetMTime() << endl;
706 // cout << "DA " << this
707 // << " GF " << myGeomFilter
708 // << " " << this->Superclass::GetMTime()
709 // << " " << myExtractGeometry->GetMTime()
710 // << " " << myExtractUnstructuredGrid->GetMTime()
711 // << " " << myMergeFilter->GetMTime()
712 // << " " << myGeomFilter->GetMTime()
713 // << " " << myTransformFilter->GetMTime()
714 // << " " << myFaceOrientationFilter->GetMTime() << endl;
716 vtkMTimeType mTime = this->Superclass::GetMTime();
717 mTime = max(mTime,myExtractGeometry->GetMTime());
718 mTime = max(mTime,myExtractUnstructuredGrid->GetMTime());
719 mTime = max(mTime,myMergeFilter->GetMTime());
720 mTime = max(mTime,myGeomFilter->GetMTime());
721 mTime = max(mTime,myTransformFilter->GetMTime());
722 mTime = max(mTime,myFaceOrientationFilter->GetMTime());
729 ::SetTransform(VTKViewer_Transform* theTransform)
731 myTransformFilter->SetTransform(theTransform);
739 if ( !myIsShrinkable ) return;
740 if ( vtkAlgorithmOutput* aDataSet = myPassFilter[ 0 ]->GetOutputPort() )
742 myShrinkFilter->SetInputConnection( aDataSet );
743 myPassFilter[ 1 ]->SetInputConnection( myShrinkFilter->GetOutputPort() );
752 if ( !myIsShrunk ) return;
753 if ( vtkAlgorithmOutput* aDataSet = myPassFilter[ 0 ]->GetOutputPort() )
755 myPassFilter[ 1 ]->SetInputConnection( aDataSet );
756 myPassFilter[ 1 ]->Modified();
765 ::SetFacesOriented(bool theIsFacesOriented)
767 if ( vtkAlgorithmOutput* aDataSet = myTransformFilter->GetOutputPort() )
769 myIsFacesOriented = theIsFacesOriented;
770 if( theIsFacesOriented )
771 myFaceOrientationFilter->SetInputConnection( aDataSet );
772 UpdateFaceOrientation();
778 ::SetFacesOrientationColor(double r,double g,double b)
780 myFaceOrientation->GetProperty()->SetColor( r, g, b );
785 ::GetFacesOrientationColor(double& r,double& g,double& b)
787 myFaceOrientation->GetProperty()->GetColor( r, g, b );
792 ::SetFacesOrientationScale(double theScale)
794 myFaceOrientationFilter->SetOrientationScale( theScale );
799 ::GetFacesOrientationScale()
801 return myFaceOrientationFilter->GetOrientationScale();
806 ::SetFacesOrientation3DVectors(bool theState)
808 myFaceOrientationFilter->Set3dVectors( theState );
813 ::GetFacesOrientation3DVectors()
815 return myFaceOrientationFilter->Get3dVectors();
820 ::UpdateFaceOrientation()
822 bool aShowFaceOrientation = myIsFacesOriented;
823 aShowFaceOrientation &= vtkLODActor::GetVisibility(); //GetVisibility(); -- avoid calling GetUnstructuredGrid()
824 aShowFaceOrientation &= ( myRepresentation != ePoint );
825 myFaceOrientation->SetVisibility(aShowFaceOrientation);
831 ::SetRepresentation(EReperesent theMode)
833 if ( myRepresentation == theMode )
837 myGeomFilter->SetInside(true);
838 myGeomFilter->SetWireframeMode(false);
839 GetProperty()->SetRepresentation(0);
842 myGeomFilter->SetInside(false);
843 myGeomFilter->SetWireframeMode(true);
844 GetProperty()->SetRepresentation(theMode);
847 myGeomFilter->SetInside(true);
848 myGeomFilter->SetWireframeMode(true);
849 GetProperty()->SetRepresentation(1);
852 myGeomFilter->SetInside(false);
853 myGeomFilter->SetWireframeMode(false);
854 GetProperty()->SetRepresentation(theMode);
858 SetMarkerEnabled(theMode == ePoint);
859 myRepresentation = theMode;
860 UpdateFaceOrientation();
861 GetProperty()->Modified();
862 myMapper->Modified();
869 ::SetVisibility(int theMode)
872 ( !myExtractUnstructuredGrid->GetInput() ||
873 GetUnstructuredGrid()->GetNumberOfCells()))
875 vtkLODActor::SetVisibility(theMode);
877 vtkLODActor::SetVisibility(false);
879 UpdateFaceOrientation();
887 int visibi = vtkLODActor::GetVisibility();
888 if(visibi && !GetUnstructuredGrid()->GetNumberOfCells()){
889 vtkLODActor::SetVisibility(false);
898 ::AddToRender(vtkRenderer* theRenderer)
900 theRenderer->AddActor(this);
901 theRenderer->AddActor(myFaceOrientation);
906 ::RemoveFromRender(vtkRenderer* theRenderer)
908 theRenderer->RemoveActor(this);
909 theRenderer->RemoveActor(myFaceOrientation);
915 ::GetNodeObjId(vtkIdType theVtkID)
917 vtkIdType anID = theVtkID;
919 if(IsImplicitFunctionUsed())
920 anID = myExtractGeometry->GetNodeObjId(theVtkID);
922 vtkIdType aRetID = myVisualObj->GetNodeObjId(anID);
923 MESSAGE("GetNodeObjId - theVtkID = "<<theVtkID<<"; anID = "<<anID<<"; aRetID = "<<aRetID);
929 ::GetNodeCoord(vtkIdType theObjID)
931 vtkDataSet* aDataSet = myMergeFilter->GetOutput();
932 vtkIdType anID = myVisualObj->GetNodeVTKId(theObjID);
933 double* aCoord = (anID >=0 && anID < aDataSet->GetNumberOfPoints()) ? aDataSet->GetPoint(anID) : NULL;
934 MESSAGE("GetNodeCoord - theObjID = "<<theObjID<<"; anID = "<<anID);
940 ::GetNodeVtkId(vtkIdType theObjID)
942 return myVisualObj->GetNodeVTKId(theObjID);
947 ::GetElemObjId(vtkIdType theVtkID)
949 vtkIdType anId = myGeomFilter->GetElemObjId(theVtkID);
953 vtkIdType anId2 = anId;
954 if(IsImplicitFunctionUsed())
955 anId2 = myExtractGeometry->GetElemObjId(anId);
959 vtkIdType anId3 = myExtractUnstructuredGrid->GetInputId(anId2);
963 vtkIdType aRetID = myVisualObj->GetElemObjId(anId3);
965 MESSAGE("GetElemObjId - theVtkID = "<<theVtkID<<"; anId2 = "<<anId2<<"; anId3 = "<<anId3<<"; aRetID = "<<aRetID);
971 ::GetElemCell(vtkIdType theObjID)
973 vtkDataSet* aDataSet = myVisualObj->GetUnstructuredGrid();
974 vtkIdType aGridID = myVisualObj->GetElemVTKId(theObjID);
975 vtkCell* aCell = (aGridID >= 0 ) ? aDataSet->GetCell(aGridID) : NULL;
977 MESSAGE("GetElemCell - theObjID = "<<theObjID<<"; aGridID = "<<aGridID);
986 return myShrinkFilter->GetShrinkFactor();
991 ::SetShrinkFactor(double theValue)
993 theValue = theValue > 0.1? theValue: 0.8;
994 myShrinkFilter->SetShrinkFactor(theValue);
1001 ::SetHighlited(bool theIsHighlited)
1003 if ( myIsHighlited == theIsHighlited )
1005 myIsHighlited = theIsHighlited;
1011 ::Render(vtkRenderer *ren, vtkMapper* m)
1013 int aResolveCoincidentTopology = vtkMapper::GetResolveCoincidentTopology();
1014 double aStoredFactor, aStoredUnit;
1015 vtkMapper::GetResolveCoincidentTopologyPolygonOffsetParameters(aStoredFactor,aStoredUnit);
1017 vtkMapper::SetResolveCoincidentTopologyToPolygonOffset();
1018 double aFactor = myPolygonOffsetFactor, aUnits = myPolygonOffsetUnits;
1020 static double EPS = .01;
1021 aUnits *= (1.0-EPS);
1023 vtkMapper::SetResolveCoincidentTopologyPolygonOffsetParameters(aFactor,aUnits);
1024 vtkLODActor::Render(ren,m);
1026 vtkMapper::SetResolveCoincidentTopologyPolygonOffsetParameters(aStoredFactor,aStoredUnit);
1027 vtkMapper::SetResolveCoincidentTopology(aResolveCoincidentTopology);
1033 ::SetPolygonOffsetParameters(double factor,
1036 myPolygonOffsetFactor = factor;
1037 myPolygonOffsetUnits = units;
1041 * On/Off representation 2D quadratic element as arked polygon
1043 void SMESH_DeviceActor::SetQuadraticArcMode(bool theFlag){
1044 myGeomFilter->SetQuadraticArcMode(theFlag);
1048 * Return true if 2D quadratic element displayed as arked polygon
1050 bool SMESH_DeviceActor::GetQuadraticArcMode(){
1051 return myGeomFilter->GetQuadraticArcMode();
1054 * Set Max angle for representation 2D quadratic element as arked polygon
1056 void SMESH_DeviceActor::SetQuadraticArcAngle(double theMaxAngle){
1057 myGeomFilter->SetQuadraticArcAngle(theMaxAngle);
1061 * Return Max angle of the representation 2D quadratic element as arked polygon
1063 double SMESH_DeviceActor::GetQuadraticArcAngle(){
1064 return myGeomFilter->GetQuadraticArcAngle();
1068 * Set point marker enabled
1069 * \param theMarkerEnabled flag to enable/disable point marker
1071 void SMESH_DeviceActor::SetMarkerEnabled( bool theMarkerEnabled )
1073 myMapper->SetMarkerEnabled( theMarkerEnabled );
1077 * Set point marker enabled
1078 * \param theBallEnabled flag to enable/disable ball drawing
1080 void SMESH_DeviceActor::SetBallEnabled( bool theBallEnabled ) {
1081 myMapper->SetBallEnabled( theBallEnabled );
1085 * Set point marker scale factor
1086 * \param theBallScale double value which specifies a scale factor of ball element
1088 void SMESH_DeviceActor::SetBallScale( double theBallScale )
1090 myMapper->SetBallScale( theBallScale );
1091 myMapper->Modified();
1095 * Set standard point marker
1096 * \param theMarkerType type of the marker
1098 void SMESH_DeviceActor::SetMarkerStd( VTK::MarkerType theMarkerType, VTK::MarkerScale theMarkerScale )
1100 myMapper->SetMarkerStd( theMarkerType, theMarkerScale );
1104 * Set custom point marker
1105 * \param theMarkerId id of the marker texture
1106 * \param theMarkerTexture marker texture
1108 void SMESH_DeviceActor::SetMarkerTexture( int theMarkerId, VTK::MarkerTexture theMarkerTexture )
1110 myMapper->SetMarkerTexture( theMarkerId, theMarkerTexture );
1114 * Get type of the point marker
1115 * \return type of the point marker
1117 VTK::MarkerType SMESH_DeviceActor::GetMarkerType()
1119 return myMapper->GetMarkerType();
1123 Get scale of the point marker
1124 \return scale of the point marker
1126 VTK::MarkerScale SMESH_DeviceActor::GetMarkerScale()
1128 return myMapper->GetMarkerScale();
1132 * Get texture identifier of the point marker
1133 * \return texture identifier of the point marker
1135 int SMESH_DeviceActor::GetMarkerTexture()
1137 return myMapper->GetMarkerTexture();
1141 * Get scale factor of ball element
1142 * \return scale factor of ball element
1144 double SMESH_DeviceActor::GetBallScale()
1146 return myMapper->GetBallScale();
1149 void SMESH_DeviceActor::SetCoincident3DAllowed(bool theFlag) {
1150 myGeomFilter->SetAppendCoincident3D(theFlag);
1153 bool SMESH_DeviceActor::IsCoincident3DAllowed() const {
1154 return myGeomFilter->GetAppendCoincident3D();