3c1e754c5214c1571ea8d46833cc57c92e185a40
[occt.git] / src / IVtkTools / IVtkTools_ShapeDataSource.cxx
1 // Created on: 2011-10-14 
2 // Created by: Roman KOZLOV
3 // Copyright (c) 2011-2014 OPEN CASCADE SAS 
4 // 
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 // VIS includes
17 #include <IVtkTools_ShapeDataSource.hxx>
18 #include <IVtkOCC_ShapeMesher.hxx>
19 #include <IVtkTools_ShapeObject.hxx>
20
21 // prevent disabling some MSVC warning messages by VTK headers 
22 #ifdef _MSC_VER
23 #pragma warning(push)
24 #endif
25 #include <vtkObjectFactory.h> 
26 #include <vtkCellData.h>
27 #include <vtkIdTypeArray.h>
28 #include <vtkInformation.h>
29 #include <vtkPoints.h>
30 #include <vtkPolyData.h>
31 #include <vtkTransform.h>
32 #include <vtkTransformPolyDataFilter.h>
33 #ifdef _MSC_VER
34 #pragma warning(pop)
35 #endif
36
37 vtkStandardNewMacro(IVtkTools_ShapeDataSource)
38
39 //================================================================
40 // Function : Constructor
41 // Purpose  : 
42 //================================================================
43 IVtkTools_ShapeDataSource::IVtkTools_ShapeDataSource()
44 : myPolyData (new IVtkVTK_ShapeData),
45   myIsFastTransformMode (Standard_False),
46   myIsTransformOnly (Standard_False)
47 {
48   this->SetNumberOfInputPorts(0);
49   this->SetNumberOfOutputPorts(1);
50 }
51
52 //================================================================
53 // Function : Destructor
54 // Purpose  : 
55 //================================================================
56 IVtkTools_ShapeDataSource::~IVtkTools_ShapeDataSource()
57 { }
58
59 //================================================================
60 // Function : SetShape
61 // Purpose  : 
62 //================================================================
63 void IVtkTools_ShapeDataSource::SetShape (const IVtkOCC_Shape::Handle& theOccShape)
64 {
65   if (myIsFastTransformMode && !myOccShape.IsNull() &&
66       theOccShape->GetShape().IsPartner (myOccShape->GetShape() ) )
67   {
68     myIsTransformOnly = Standard_True;
69   }
70   else
71   {
72     myIsTransformOnly = Standard_False;
73   }
74
75   myOccShape = theOccShape;
76   this->Modified();
77 }
78
79 //================================================================
80 // Function : GetShape
81 // Purpose  : 
82 //================================================================
83 IVtkOCC_Shape::Handle IVtkTools_ShapeDataSource::GetShape()
84 {
85   return myOccShape;
86 }
87
88 //================================================================
89 // Function : RequestData
90 // Purpose  : 
91 //================================================================
92 int IVtkTools_ShapeDataSource::RequestData(vtkInformation        *vtkNotUsed(theRequest),
93                                            vtkInformationVector **vtkNotUsed(theInputVector),
94                                            vtkInformationVector  *theOutputVector)
95 {
96   vtkSmartPointer<vtkPolyData> aPolyData = vtkPolyData::GetData (theOutputVector);
97   if (aPolyData.GetPointer() != NULL)
98   {
99     aPolyData->Allocate();
100     vtkSmartPointer<vtkPoints> aPts = vtkSmartPointer<vtkPoints>::New();
101     aPolyData->SetPoints (aPts);
102
103     vtkSmartPointer<vtkPolyData> aTransformedData;
104     TopoDS_Shape aShape = myOccShape->GetShape();
105     TopLoc_Location aShapeLoc = aShape.Location();
106
107     if (myIsTransformOnly)
108     {
109       vtkSmartPointer<vtkPolyData> aPrevData = myPolyData->getVtkPolyData();
110       if ( !aShapeLoc.IsIdentity() )
111       {
112         aTransformedData = this->transform (aPrevData, aShapeLoc);
113       }
114       else
115       {
116         aTransformedData = aPrevData;
117       }
118     }
119     else
120     {
121       IVtkOCC_Shape::Handle aShapeWrapperCopy;
122       if ( myIsFastTransformMode && !aShapeLoc.IsIdentity() )
123       {
124         // Reset location before meshing
125         aShape.Location (TopLoc_Location());
126         aShapeWrapperCopy = new IVtkOCC_Shape (aShape);
127         aShapeWrapperCopy->SetId (myOccShape->GetId());
128       }
129       else
130       {
131         aShapeWrapperCopy = myOccShape;
132       }
133
134       myPolyData = new IVtkVTK_ShapeData;
135       IVtkOCC_ShapeMesher::Handle aMesher = new IVtkOCC_ShapeMesher;
136       aMesher->Build (aShapeWrapperCopy, myPolyData);
137       vtkSmartPointer<vtkPolyData> aMeshData = myPolyData->getVtkPolyData();
138
139       if ( myIsFastTransformMode && !aShapeLoc.IsIdentity() )
140       {
141         aTransformedData = this->transform (aMeshData, aShapeLoc);
142       }
143       else
144       {
145         aTransformedData = aMeshData;
146       }
147     }
148
149     aPolyData->CopyStructure (aTransformedData);  // Copy points and cells
150     aPolyData->CopyAttributes (aTransformedData); // Copy data arrays (sub-shapes IDs)
151
152     // We store the OccShape instance in a IVtkTools_ShapeObject
153     // wrapper in vtkInformation object of vtkDataObject, then pass it
154     // to the actors through pipelines, so selection logic can access
155     // OccShape easily given the actor instance.
156     IVtkTools_ShapeObject::SetShapeSource (this, aPolyData);
157     aPolyData->GetAttributes (vtkDataObject::CELL)->SetPedigreeIds (SubShapeIDs());
158   }
159
160   return 1;
161 }
162
163 //================================================================
164 // Function : SubShapeIDs
165 // Purpose  : 
166 //================================================================
167 vtkSmartPointer<vtkIdTypeArray> IVtkTools_ShapeDataSource::SubShapeIDs()
168 {
169   vtkSmartPointer<vtkDataArray> arr = 
170     GetOutput()->GetCellData()->GetArray(IVtkVTK_ShapeData::ARRNAME_SUBSHAPE_IDS);
171   return vtkSmartPointer<vtkIdTypeArray>( 
172     vtkIdTypeArray::SafeDownCast(arr.GetPointer()) );
173 }
174
175 //================================================================
176 // Function : GetId
177 // Purpose  : 
178 //================================================================
179 IVtk_IdType IVtkTools_ShapeDataSource::GetId() const
180 {
181   return myOccShape.IsNull() ? -1 : myOccShape->GetId();
182 }
183
184 //================================================================
185 // Function : Contains
186 // Purpose  : 
187 //================================================================
188 Standard_Boolean IVtkTools_ShapeDataSource::Contains (const IVtkOCC_Shape::Handle& shape) const
189 {
190   return ((myOccShape == shape) ? Standard_True : Standard_False);
191 }
192
193 //================================================================
194 // Function : transform
195 // Purpose  : 
196 //================================================================
197 vtkSmartPointer<vtkPolyData> IVtkTools_ShapeDataSource::transform (vtkPolyData* theSource,
198                                                                    const gp_Trsf& theTrsf) const
199 {
200   vtkSmartPointer<vtkPolyData> aResult = vtkSmartPointer<vtkPolyData>::New();
201   aResult->Allocate();
202   vtkSmartPointer<vtkPoints> aPts = vtkSmartPointer<vtkPoints>::New();
203   aResult->SetPoints (aPts);
204
205   vtkSmartPointer<vtkTransform> aTransform = vtkSmartPointer<vtkTransform>::New();
206   vtkSmartPointer<vtkMatrix4x4> aMx = vtkSmartPointer<vtkMatrix4x4>::New();
207   for (Standard_Integer aRow = 0; aRow < 3; ++aRow)
208     for (Standard_Integer aCol = 0; aCol < 4; ++aCol)
209     {
210       aMx->SetElement (aRow, aCol, theTrsf.Value (aRow + 1, aCol + 1) );
211     }
212
213   aTransform->SetMatrix (aMx);
214   vtkSmartPointer<vtkTransformPolyDataFilter> aTrsfFilter
215     = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
216
217   aTrsfFilter->SetTransform (aTransform);
218   aTrsfFilter->SetInputData (theSource);
219   aTrsfFilter->Update();
220
221   vtkSmartPointer<vtkPolyData> aTransformed = aTrsfFilter->GetOutput();
222   aResult->CopyStructure (aTransformed);  // Copy points and cells
223   aResult->CopyAttributes (aTransformed); // Copy data arrays (sub-shapes ids)
224
225   return aResult;
226 }