dda4ec5cb6048526e63a3c871833409d8690e93d
[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 <IVtkOCC_ShapeMesher.hxx>
18 #include <IVtkTools_ShapeDataSource.hxx>
19 #include <IVtkTools_ShapeObject.hxx>
20
21 // VTK includes
22 #include <vtkCellArray.h>
23 #include <vtkCellData.h>
24 #include <vtkDoubleArray.h>
25 #include <vtkIdTypeArray.h>
26 #include <vtkInformation.h>
27 #include <vtkObjectFactory.h> 
28 #include <vtkPoints.h>
29 #include <vtkPolyData.h>
30 #include <vtkStreamingDemandDrivenPipeline.h>
31 #include <vtkTransform.h>
32 #include <vtkTransformPolyDataFilter.h>
33
34 vtkStandardNewMacro(IVtkTools_ShapeDataSource);
35
36 //================================================================
37 // Function : Constructor
38 // Purpose  : 
39 //================================================================
40 IVtkTools_ShapeDataSource::IVtkTools_ShapeDataSource()
41 : myPolyData (new IVtkVTK_ShapeData),
42   myIsFastTransformMode (Standard_False),
43   myIsTransformOnly (Standard_False)
44 {
45   this->SetNumberOfInputPorts (0);
46 }
47
48 //================================================================
49 // Function : Destructor
50 // Purpose  : 
51 //================================================================
52 IVtkTools_ShapeDataSource::~IVtkTools_ShapeDataSource()
53 { }
54
55 //================================================================
56 // Function : SetShape
57 // Purpose  : 
58 //================================================================
59 void IVtkTools_ShapeDataSource::SetShape (const IVtkOCC_Shape::Handle& theOccShape)
60 {
61   if (myIsFastTransformMode && !myOccShape.IsNull() &&
62       theOccShape->GetShape().IsPartner (myOccShape->GetShape() ) )
63   {
64     myIsTransformOnly = Standard_True;
65   }
66   else
67   {
68     myIsTransformOnly = Standard_False;
69   }
70
71   myOccShape = theOccShape;
72   this->Modified();
73 }
74
75 //================================================================
76 // Function : GetShape
77 // Purpose  : 
78 //================================================================
79 IVtkOCC_Shape::Handle IVtkTools_ShapeDataSource::GetShape()
80 {
81   return myOccShape;
82 }
83
84 //================================================================
85 // Function : RequestData
86 // Purpose  : 
87 //================================================================
88 int IVtkTools_ShapeDataSource::RequestData (vtkInformation* theRequest,
89                                             vtkInformationVector** theInputVector,
90                                             vtkInformationVector* theOutputVector)
91 {
92   vtkPolyData* aPolyData = vtkPolyData::GetData (theOutputVector);
93   aPolyData->Allocate();
94   vtkPoints* aPts = vtkPoints::New();
95   aPolyData->SetPoints (aPts);
96   aPts->Delete();
97
98   vtkSmartPointer<vtkPolyData> aTransformedData;
99   TopoDS_Shape aShape = myOccShape->GetShape();
100   TopLoc_Location aShapeLoc = aShape.Location();
101
102   if (myIsTransformOnly)
103   {
104     vtkPolyData* aPrevData = myPolyData->getVtkPolyData();
105     if (!aShapeLoc.IsIdentity() )
106     {
107       aTransformedData = this->transform (aPrevData, aShapeLoc);
108     }
109     else
110     {
111       aTransformedData = aPrevData;
112     }
113   }
114   else
115   {
116     IVtkOCC_Shape::Handle aShapeWrapperCopy;
117     if (myIsFastTransformMode && !aShapeLoc.IsIdentity() )
118     {
119       // Reset location before meshing
120       aShape.Location (TopLoc_Location() );
121       aShapeWrapperCopy = new IVtkOCC_Shape (aShape);
122       aShapeWrapperCopy->SetId (myOccShape->GetId() );
123     }
124     else
125     {
126       aShapeWrapperCopy = myOccShape;
127     }
128
129     myPolyData = new IVtkVTK_ShapeData;
130     IVtkOCC_ShapeMesher::Handle aMesher = new IVtkOCC_ShapeMesher;
131     aMesher->Build (aShapeWrapperCopy, myPolyData);
132     vtkPolyData* aMeshData = myPolyData->getVtkPolyData();
133
134     if (myIsFastTransformMode && !aShapeLoc.IsIdentity() )
135     {
136       aTransformedData = this->transform (aMeshData, aShapeLoc);
137     }
138     else
139     {
140       aTransformedData = aMeshData;
141     }
142   }
143
144   aPolyData->CopyStructure (aTransformedData);  // Copy points and cells
145   aPolyData->CopyAttributes (aTransformedData); // Copy data arrays (sub-shapes IDs)
146
147   // We store the OccShape instance in a IVtkTools_ShapeObject
148   // wrapper in vtkInformation object of vtkDataObject, then pass it
149   // to the actors through pipelines, so selection logic can access
150   // OccShape easily given the actor instance.
151   IVtkTools_ShapeObject::SetShapeSource (this, aPolyData);
152   aPolyData->GetAttributes (vtkDataObject::CELL)->SetPedigreeIds (SubShapeIDs() );
153
154   return Superclass::RequestData (theRequest, theInputVector, theOutputVector);
155 }
156
157 //================================================================
158 // Function : SubShapeIDs
159 // Purpose  : 
160 //================================================================
161 vtkSmartPointer<vtkIdTypeArray> IVtkTools_ShapeDataSource::SubShapeIDs()
162 {
163   vtkDataArray* arr = GetOutput()->GetCellData()->GetArray(IVtkVTK_ShapeData::ARRNAME_SUBSHAPE_IDS);
164   return vtkSmartPointer<vtkIdTypeArray>( vtkIdTypeArray::SafeDownCast(arr) );
165 }
166
167 //================================================================
168 // Function : GetId
169 // Purpose  : 
170 //================================================================
171 IVtk_IdType IVtkTools_ShapeDataSource::GetId() const
172 {
173   return myOccShape ? myOccShape->GetId() : -1;
174 }
175
176 //================================================================
177 // Function : Contains
178 // Purpose  : 
179 //================================================================
180 Standard_Boolean IVtkTools_ShapeDataSource::Contains (const IVtkOCC_Shape::Handle& shape) const
181 {
182   return ((myOccShape == shape) ? Standard_True : Standard_False);
183 }
184
185 //================================================================
186 // Function : transform
187 // Purpose  : 
188 //================================================================
189 vtkSmartPointer<vtkPolyData> IVtkTools_ShapeDataSource::transform (vtkPolyData* theSource,
190                                                                    const gp_Trsf& theTrsf) const
191 {
192   vtkSmartPointer<vtkPolyData> aResult = vtkSmartPointer<vtkPolyData>::New();
193   aResult->Allocate();
194   vtkSmartPointer<vtkPoints> aPts = vtkSmartPointer<vtkPoints>::New();
195   aResult->SetPoints (aPts);
196
197   vtkSmartPointer<vtkTransform> aTransform = vtkSmartPointer<vtkTransform>::New();
198   vtkSmartPointer<vtkMatrix4x4> aMx = vtkSmartPointer<vtkMatrix4x4>::New();
199   for (Standard_Integer aRow = 0; aRow < 3; ++aRow)
200     for (Standard_Integer aCol = 0; aCol < 4; ++aCol)
201     {
202       aMx->SetElement (aRow, aCol, theTrsf.Value (aRow + 1, aCol + 1) );
203     }
204
205   aTransform->SetMatrix (aMx);
206   vtkSmartPointer<vtkTransformPolyDataFilter> aTrsfFilter
207     = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
208
209   aTrsfFilter->SetTransform (aTransform);
210   aTrsfFilter->SetInputData (theSource);
211   aTrsfFilter->Update();
212
213   vtkPolyData* aTransformed = aTrsfFilter->GetOutput();
214   aResult->CopyStructure (aTransformed);  // Copy points and cells
215   aResult->CopyAttributes (aTransformed); // Copy data arrays (sub-shapes ids)
216
217   return aResult;
218 }