Commit 5d14f5ad authored by Yumin Yuan's avatar Yumin Yuan

Merge pull request #250 from yumin/discrete_full3D_io

Made vtk parsers and writers in discrete bridge to handle full 3D topology.
parents 315fb5b5 11b0683c
......@@ -125,7 +125,9 @@ void vtkCMBModelWriterV2::SetAnalysisGridData(vtkDiscreteModel* model, vtkPolyDa
vtkIdTypeArray* pointMap = analysisGridInfo->GetModelPointToAnalysisPoint();
vtkIdTypeArray* cellMap = analysisGridInfo->GetModelCellToAnalysisCells();
vtkCharArray* cellSides = analysisGridInfo->GetModelCellToAnalysisCellSides();
if(pointMap != NULL && cellMap != NULL && cellSides != NULL)
if((pointMap != NULL && pointMap->GetNumberOfTuples() == poly->GetNumberOfPoints()) &&
(cellMap != NULL && cellMap->GetNumberOfTuples() == poly->GetNumberOfCells()) &&
(cellSides != NULL && cellSides->GetNumberOfTuples() == poly->GetNumberOfCells()))
{
pointMap->SetName(vtkDiscreteModel::GetPointMapArrayName());
poly->GetPointData()->AddArray(pointMap);
......
......@@ -59,7 +59,7 @@ void vtkCMBModelWriterV5::SetModelEdgeData(vtkDiscreteModel* model, vtkPolyData*
for(edges->Begin();!edges->IsAtEnd();edges->Next())
{
vtkDiscreteModelEdge* edge = vtkDiscreteModelEdge::SafeDownCast(edges->GetCurrentItem());
if(edge->GetModelRegion() != NULL || model->GetModelDimension() == 2)
// if(edge->GetModelRegion() != NULL || model->GetModelDimension() == 2)
{
entities.push_back(edge);
}
......@@ -116,7 +116,7 @@ void vtkCMBModelWriterV5::SetModelEdgeData(vtkDiscreteModel* model, vtkPolyData*
void vtkCMBModelWriterV5::SetModelFaceData(vtkDiscreteModel* Model, vtkPolyData* Poly)
{
std::vector<vtkModelEntity*> Entities;
if(Model->GetModelDimension() == 2)
// if(Model->GetModelDimension() == 2)
{
// the adjacent edge ids for each model face is separated by a -1
vtkIdTypeArray* ModelFaceAdjacentEdgesId = vtkIdTypeArray::New();
......@@ -130,7 +130,10 @@ void vtkCMBModelWriterV5::SetModelFaceData(vtkDiscreteModel* Model, vtkPolyData*
vtkDiscreteModelFace* Face = vtkDiscreteModelFace::SafeDownCast(Faces->GetCurrentItem());
Entities.push_back(Face);
vtkModelMaterial* Material = Face->GetMaterial();
ModelFaceMaterialIds->InsertNextValue(Material->GetUniquePersistentId());
if(Material)
{
ModelFaceMaterialIds->InsertNextValue(Material->GetUniquePersistentId());
}
// Loop Information is encoded as follows: nL l0e0 l0e1 ... -1 l1e0 ...
// Where nL is the number of loops in the face followed by the edges in
// loop (for example l0e0 is edge 0 of loop 0) - with each loop separated by -1
......@@ -173,12 +176,14 @@ void vtkCMBModelWriterV5::SetModelFaceData(vtkDiscreteModel* Model, vtkPolyData*
ModelEdgeDirections->SetName(ModelParserHelper::GetModelEdgeDirectionsString());
Poly->GetFieldData()->AddArray(ModelEdgeDirections);
ModelEdgeDirections->Delete();
ModelFaceMaterialIds->SetName(ModelParserHelper::GetFaceMaterialIdString());
Poly->GetFieldData()->AddArray(ModelFaceMaterialIds);
if(ModelFaceMaterialIds->GetNumberOfTuples())
{
ModelFaceMaterialIds->SetName(ModelParserHelper::GetFaceMaterialIdString());
Poly->GetFieldData()->AddArray(ModelFaceMaterialIds);
}
ModelFaceMaterialIds->Delete();
}
else if(Model->GetModelDimension() == 3)
if(Model->GetModelDimension() == 3)
{
vtkIdTypeArray* ModelFaceAdjacentRegionsId = vtkIdTypeArray::New();
ModelFaceAdjacentRegionsId->SetNumberOfComponents(2);
......@@ -187,7 +192,7 @@ void vtkCMBModelWriterV5::SetModelFaceData(vtkDiscreteModel* Model, vtkPolyData*
for(Faces->Begin();!Faces->IsAtEnd();Faces->Next())
{
vtkDiscreteModelFace* Face = vtkDiscreteModelFace::SafeDownCast(Faces->GetCurrentItem());
Entities.push_back(Face);
// Entities.push_back(Face);
vtkIdType ids[2] = {-1, -1};
for(int j=0;j<2;j++)
{
......
......@@ -224,34 +224,11 @@ bool vtkCMBParserV5::Parse(vtkPolyData* MasterPoly, vtkDiscreteModel* Model,
// Create the face
vtkDiscreteModelFace* face;
if(FaceMaterials && FaceMaterials->GetValue(i) >= 0)
{ // a model face in a 2D model
// First get the number of loops
int nLoops = EdgesOfModelFace->GetValue(ArrayCounter++);
int loop;
{
vtkModelMaterial* Material = vtkModelMaterial::SafeDownCast(
Model->GetModelEntity(vtkModelMaterialType, FaceMaterials->GetValue(i)));
face = vtkDiscreteModelFace::SafeDownCast(
Model->BuildModelFace(0, NULL, NULL, Material) );
// Process each face loop (assume that the first loop is the outer one
for (loop = 0; loop < nLoops; ++loop)
{
int EdgeCounter = 0;
while(ArrayCounter < EdgesOfModelFace->GetNumberOfTuples() &&
EdgesOfModelFace->GetValue(ArrayCounter) >= 0)
{
vtkIdType EdgeId = EdgesOfModelFace->GetValue(ArrayCounter);
Edges[EdgeCounter] =
vtkModelEdge::SafeDownCast(Model->GetModelEntity(vtkModelEdgeType, EdgeId));
EdgeDirs[EdgeCounter] = EdgeDirections->GetValue(ArrayCounter);
ArrayCounter++;
EdgeCounter++;
}
ArrayCounter++; // incremented because we want to skip the -1 value
bool blockEvent = Model->GetBlockModelGeometricEntityEvent();
Model->SetBlockModelGeometricEntityEvent(true);
face->AddLoop(EdgeCounter, &Edges[0], &EdgeDirs[0]);
Model->SetBlockModelGeometricEntityEvent(blockEvent);
}
}
else
{ // a model face in a 3D model
......@@ -277,8 +254,36 @@ bool vtkCMBParserV5::Parse(vtkPolyData* MasterPoly, vtkDiscreteModel* Model,
}
}
}
if(EdgesOfModelFace && EdgesOfModelFace->GetNumberOfTuples() > 0)
{ // a model face in a 2D model
// First get the number of loops
int nLoops = EdgesOfModelFace->GetValue(ArrayCounter++);
int loop;
// Process each face loop (assume that the first loop is the outer one
for (loop = 0; loop < nLoops; ++loop)
{
int EdgeCounter = 0;
while(ArrayCounter < EdgesOfModelFace->GetNumberOfTuples() &&
EdgesOfModelFace->GetValue(ArrayCounter) >= 0)
{
vtkIdType EdgeId = EdgesOfModelFace->GetValue(ArrayCounter);
Edges[EdgeCounter] =
vtkModelEdge::SafeDownCast(Model->GetModelEntity(vtkModelEdgeType, EdgeId));
EdgeDirs[EdgeCounter] = EdgeDirections->GetValue(ArrayCounter);
ArrayCounter++;
EdgeCounter++;
}
ArrayCounter++; // incremented because we want to skip the -1 value
bool blockEvent = Model->GetBlockModelGeometricEntityEvent();
Model->SetBlockModelGeometricEntityEvent(true);
face->AddLoop(EdgeCounter, &Edges[0], &EdgeDirs[0]);
Model->SetBlockModelGeometricEntityEvent(blockEvent);
}
}
ModelEntities[i] = face;
}
if(EdgesOfModelFace)
{
EdgesOfModelFace->Delete();
......
......@@ -6,6 +6,7 @@ set(smtkDiscreteSessionPythonTests
set(smtkDiscreteSessionPythonDataTests
discreteBathymetry
discreteCreateEdges
discreteCreateAndSaveEdges
discreteReadFile
discreteSplitEdge
)
......
#!/usr/bin/python
#=============================================================================
#
# Copyright (c) Kitware, Inc.
# All rights reserved.
# See LICENSE.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even
# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the above copyright notice for more information.
#
#=============================================================================
import os
import sys
import smtk
import smtk.testing
from smtk.simple import *
class TestDiscreteCreateAndSaveEdges(smtk.testing.TestCase):
def resetTestFiles(self):
self.filesToTest = []
def addExternalFile(self, pathStr, validator = None):
self.filesToTest += [{'filename':pathStr, 'validator':validator}]
def addTestFile(self, pathList, validator = None):
self.addExternalFile(
os.path.join(*([smtk.testing.DATA_DIR,] + pathList)),
validator)
def validateCreateAndSaveEdges(self, model):
if self.haveVTK() and self.haveVTKExtension():
self.startRenderTest()
mbs = self.addModelToScene(model)
self.renderer.SetBackground(0.5,0.5,1)
ac = self.renderer.GetActors()
ac.InitTraversal()
act = ac.GetNextActor()
act.GetProperty().SetLineWidth(2)
act.GetProperty().SetPointSize(8)
act.GetMapper().SetResolveCoincidentTopologyToPolygonOffset()
cam = self.renderer.GetActiveCamera()
cam.SetFocalPoint(0., 0., 0.)
cam.SetPosition(15,-10,-20)
cam.SetViewUp(0,1,0)
self.renderer.ResetCamera()
self.renderWindow.Render()
self.assertImageMatch(['baselines', 'discrete', 'createedges-hybridModelOneCube.png'])
self.interact()
def setUp(self):
import os, sys
self.resetTestFiles()
self.addTestFile(['cmb', 'hybridModelOneCube.cmb'], self.validateCreateAndSaveEdges)
self.mgr = smtk.model.Manager.create()
sess = self.mgr.createSession('discrete')
sess.assignDefaultName()
SetActiveSession(sess)
self.shouldSave = False
def verifyCreateAndSaveEdges(self, filename, validator):
"""Read a single file and validate that the operator worked.
This is done by checking number of cells greater than zero
reported by the output model as well as running an optional
function on the model to do further model-specific testing."""
print '\n\nFile: {fname}'.format(fname=filename)
mod = smtk.model.Model(Read(filename)[0])
self.assertEqual(len(mod.cells()), 2, 'Expected {nc} free cells'.format(nc=2))
btm = GetActiveSession().op('create edges')
self.assertIsNotNone(btm, 'Missing create edges operator.')
SetVectorValue(btm.findAsModelEntity('model'), [mod,])
res = btm.operate()
sys.stdout.flush()
self.assertEqual(res.findInt('outcome').value(0), smtk.model.OPERATION_SUCCEEDED,
'create edges failed.')
writeop = GetActiveSession().op('write')
self.assertIsNotNone(writeop, 'Missing discrete write operator.')
SetVectorValue(writeop.findAsModelEntity('model'), [mod,])
tmpfile = ['testCreateAndSaveEdges.cmb',]
outfilename = os.path.join(*([smtk.testing.TEMP_DIR,] + tmpfile))
writeop.findAsFile('filename').setValue(0, outfilename)
res = writeop.operate()
sys.stdout.flush()
self.assertEqual(res.findInt('outcome').value(0), smtk.model.OPERATION_SUCCEEDED,
'write SimpleBox model with edges failed.')
mod = smtk.model.Model(Read(outfilename)[0])
self.assertEqual(len(mod.cells()), 2, 'Expected {nc} free cells'.format(nc=2))
if validator:
validator(mod)
print ' Success'
def testCreateAndSaveEdges(self):
"Read each file named in setUp and validate the reader worked."
for test in self.filesToTest:
self.verifyCreateAndSaveEdges(test['filename'], test['validator'])
if self.shouldSave:
out = file('testcreateandsaveedges.json', 'w')
print >>out, smtk.io.ExportJSON.fromModelManager(self.mgr)
out.close()
if __name__ == '__main__':
smtk.testing.process_arguments()
smtk.testing.main()
......@@ -43,6 +43,36 @@ class TestDiscreteSession(smtk.testing.TestCase):
innerEdge = inner[0].edgeUses()[0].edge()
self.assertEqual(innerEdge.name(), 'Edge10', 'Face4\'s inner loop should one edge named "Edge10"')
def validateHybrid(self, model):
"Verify that the hybridModelOneCube model is imported correctly."
faces = [smtk.model.Face(x) for x in model.cells()]
f7l = [f for f in faces if f.name() == 'Face7']
self.assertEqual(len(f7l), 1, 'Could not find floating "Face7" in hybridModelOneCube')
face7 = f7l[0]
outer = face7.positiveUse().loops()
self.assertEqual(len(outer), 0, 'Face7 should have 0 outer loop')
if self.haveVTK() and self.haveVTKExtension():
self.startRenderTest()
mbs = self.addModelToScene(model)
self.renderer.SetBackground(0.5,0.5,1)
cam = self.renderer.GetActiveCamera()
cam.SetFocalPoint(0., 0., 0.)
cam.SetPosition(15,-10,-20)
cam.SetViewUp(0,1,0)
self.renderer.ResetCamera()
self.renderWindow.Render()
self.assertImageMatch(['baselines', 'discrete', 'hybridModelOneCube.png'])
self.interact()
else:
self.assertFalse(
self.haveVTKExtension(),
'Could not import vtk. Python path is {pp}'.format(pp=sys.path))
def validatePMDC(self, model):
"Verify that the PMDC model is imported correctly."
# Assign a color to each face in the groups.
......@@ -102,6 +132,7 @@ class TestDiscreteSession(smtk.testing.TestCase):
self.addTestFile(['cmb', 'SimpleBox.cmb'], 1, 2)
self.addTestFile(['cmb', 'smooth_surface.cmb'], 6, 0)
self.addTestFile(['cmb', 'pmdc.cmb'], 7, 13, self.validatePMDC)
self.addTestFile(['cmb', 'hybridModelOneCube.cmb'], 2, 1, self.validateHybrid)
self.mgr = smtk.model.Manager.create()
sess = self.mgr.createSession('discrete')
......
......@@ -100,11 +100,14 @@ class TestDiscreteSplitEdge(smtk.testing.TestCase):
ac = self.renderer.GetActors()
ac.InitTraversal()
act = ac.GetNextActor()
act.GetProperty().SetLineWidth(5)
act.GetProperty().SetLineWidth(2)
act.GetProperty().SetPointSize(8)
act.GetMapper().SetResolveCoincidentTopologyToPolygonOffset()
cam = self.renderer.GetActiveCamera()
self.renderer.ResetCamera()
self.renderWindow.Render()
self.assertImageMatchIfFileExists(['baselines', 'discrete', 'edge-split-test2D.png'])
self.assertImageMatch(['baselines', 'discrete', 'edge-split-test2D.png'])
self.interact()
def setUp(self):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment