Commit 4d6bf7ab authored by David Thompson's avatar David Thompson
Browse files

Fix polygon import.

Faces with holes must specify "counts" that indicate which edges
make up the outer loop and which make up each inner loop.

Also color faces in the import test so that when one face fills
the hole of another there is a way to verify that the 2 faces
are tessellated properly.
parent 8161c2fe
......@@ -52,6 +52,19 @@ namespace smtk {
typedef std::vector<std::pair<smtk::model::Edge,bool> > EdgesWithOrientation;
// Debug utility:
#if 0
template<typename T>
void printPointSeq(const char* msg, T start, T end)
{
std::cout << msg << "\n";
for (T it = start; it != end; ++it)
{
std::cout << " " << it->x() << " " << it->y() << "\n";
}
}
#endif // 0
/// Ensure that we are provided the proper edge orientations in addition to the usual checks.
bool ForceCreateFace::ableToOperate()
{
......@@ -247,6 +260,7 @@ smtk::model::OperatorResult ForceCreateFace::operateInternal()
{
this->pointsForLoop(polypts, *countIt, edgeIt, modelItem->end(), edgeDirIt, edgeDirItem->end(), outerLoopEdges);
}
//printPointSeq("outer loop", polypts.begin(), polypts.end());
pface.set(polypts.begin(), polypts.end());
}
......@@ -275,6 +289,11 @@ smtk::model::OperatorResult ForceCreateFace::operateInternal()
{
this->pointsForLoop(polypts, *countIt, edgeIt, modelItem->end(), edgeDirIt, edgeDirItem->end(), innerLoopsEdges.back());
}
/*
char holemsg[512];
sprintf(holemsg, " inner loop %d ", h);
printPointSeq(holemsg, polypts.begin(), polypts.end());
*/
// Add to polygon_set_data
poly::polygon_data<internal::Coord> loop;
loop.set(polypts.begin(), polypts.end());
......
......@@ -35,6 +35,8 @@
#include "smtk/bridge/polygon/Import_xml.h"
#include "smtk/io/ExportJSON.h"
#include "vtkCellArray.h"
#include "vtkCellData.h"
#include "vtkDataSetSurfaceFilter.h"
......@@ -42,9 +44,9 @@
#include "vtkNew.h"
#include "vtkPDataSetReader.h"
#include "vtkPolyData.h"
#include "vtkXMLPolyDataWriter.h"
#include <vtksys/SystemTools.hxx>
#include "smtk/io/ExportJSON.h"
#include "cJSON.h"
using namespace smtk::model;
......@@ -64,13 +66,15 @@ int polyLines2modelEdges(vtkPolyData *mesh,
{
double p[3];
// create edge for current line cell
std::vector<double> ptscoords;
pointsItem->setNumberOfValues(npts * 3);
for (vtkIdType j=0; j < npts; ++j)
{
mesh->GetPoint(pts[j],p);
ptscoords.insert(ptscoords.end(), &p[0], p+3);
for (int i = 0; i < 3; ++i)
{
pointsItem->setValue(3 * j + i, p[i]);
}
}
pointsItem->setValues(ptscoords.begin(), ptscoords.end());
OperatorResult edgeResult = edgeOp->operate();
if (edgeResult->findInt("outcome")->value() != OPERATION_SUCCEEDED)
{
......@@ -122,11 +126,14 @@ int polyLines2modelEdgesAndFaces(vtkPolyData *mesh,
vtkIdType *pts,npts;
for (lines->SetTraversalLocation(0);lines->GetNextCell(npts,pts); ++pidx)
{
std::vector<int> counts; // how many edges make up the outer loop, how many inner loops are there and how many edges for each?
smtk::model::EntityRefArray createdEds;
// create edge for current line cell
int numNewEdges = polyLines2modelEdges(mesh, edgeOp, createdEds, pointsItem,
pts, npts, logger);
counts.push_back(numNewEdges);
counts.push_back(0);
// peek at next pedigree id if possible, to see if the pedId is the same, if yes,
// the next cell is the inner loop
if (pedigree && numNewEdges > 0)
......@@ -138,8 +145,10 @@ int polyLines2modelEdgesAndFaces(vtkPolyData *mesh,
// The next line cell is an inner loop
if(lines->GetNextCell(npts,pts))
{
++counts[1]; // increment the number of inner loops
numNewEdges += polyLines2modelEdges(mesh, edgeOp, createdEds, pointsItem,
pts, npts, logger);
counts.push_back(numNewEdges);
}
//std::cout << "inner pedid: " << pedId << std::endl;
++pidx;
......@@ -152,8 +161,10 @@ int polyLines2modelEdgesAndFaces(vtkPolyData *mesh,
//std::cout << "number of created new edges: " << createdEds.size() << std::endl;
smtk::attribute::IntItem::Ptr orientArr = faceSpec->findInt("orientations");
std::vector<int> orients (numNewEdges, -1);
//orients[0] = 1; // first one is outer loop
orients[0] = +1; // first one is outer loop
orientArr->setValues(orients.begin(), orients.end());
smtk::attribute::IntItem::Ptr countsArr = faceSpec->findInt("counts");
countsArr->setValues(counts.begin(), counts.end());
OperatorResult faceResult = faceOp->operate();
if (faceResult->findInt("outcome")->value() != OPERATION_SUCCEEDED)
......@@ -402,6 +413,13 @@ OperatorResult Import::operateInternal()
smtkInfoMacro(log(), "CreateModel operator failed.");
result = this->createResult(OPERATION_FAILED);
}
/*
vtkNew<vtkXMLPolyDataWriter> pdw;
pdw->SetFileName("/tmp/shapepoly.vtp");
pdw->SetInputDataObject(polyOutput);
pdw->Write();
*/
smtk::model::Model model = modResult->findModelEntity("created")->value();
int numEdges = polyLines2modelEdgesAndFaces(polyOutput, model, sess, log());
smtkDebugMacro(log(), "Number of edges: " << numEdges << "\n");
......
......@@ -19,7 +19,7 @@ import smtk.testing
class TestPolygonImport(smtk.testing.TestCase):
def setUp(self):
self.writeJSON = True
self.writeJSON = False
self.mgr = smtk.model.Manager.create()
sess = self.mgr.createSession('polygon')
brg = sess.session()
......@@ -40,10 +40,19 @@ class TestPolygonImport(smtk.testing.TestCase):
#opnames = sess.operatorNames()
#print opnames
def color(self, i):
# Brewer pastel1:
colors = [0xFBB4AE, 0xB3CDE3, 0xCCEBC5, 0xDECBE4, 0xFED9A6, 0xFFFFCC, 0xE5D8BD, 0xFDDAEC, 0xF2F2F2]
# Brewer qualitative set1:
colors = [0xE41A1C, 0x377EB8, 0x4DAF4A, 0x984EA3, 0xFF7F00, 0xFFFF33, 0xA65628, 0xF781BF, 0x999999]
im = i % len(colors)
col = colors[im]
return ((col/256/256)/255.0, (col/256 % 256)/255.0, (col % 256)/255.0, 1.0)
def testImportShapefile(self):
iop = GetActiveSession().op('import')
iop.findAsFile('filename').setValue( \
os.path.join(smtk.testing.DATA_DIR, 'gis', 'ponds_lidar_cropped.shp'))
os.path.join(smtk.testing.DATA_DIR, 'gis', 'countries.shp'))
res = iop.operate()
print '----'
PrintResultLog(res, always=True)
......@@ -55,17 +64,23 @@ class TestPolygonImport(smtk.testing.TestCase):
mod = smtk.model.Model(cre.value(0))
if self.writeJSON:
smtk.io.ExportJSON.fromModelManagerToFile(self.mgr, '/tmp/shapefile.json')
print 'Wrote /tmp/shapefile.json'
if self.haveVTK() and self.haveVTKExtension():
self.startRenderTest()
mod = smtk.model.Model(mod)
[mod.addCell(x) for x in self.mgr.findEntitiesOfType(smtk.model.CELL_ENTITY, False)]
freeCells = mod.cells()
# Color faces:
for i in range(len(freeCells)):
freeCells[i].setColor(self.color(i) if freeCells[i].isFace() else (0,0,0,1))
ms, vs, mp, ac = self.addModelToScene(mod)
ac.GetProperty().SetLineWidth(2)
ac.GetProperty().SetPointSize(6)
self.renderer.SetBackground(255, 255, 255)
cam = self.renderer.GetActiveCamera()
cam.SetFocalPoint(5,5,0)
cam.SetPosition(5,5,5)
......
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