Commit 2ff359c0 authored by David Thompson's avatar David Thompson
Browse files

Add more methods for bridge classes to use.

This makes it much easier for Bridge subclasses to create
cell-use records with specified UUIDs. This should also
improve (shiboken-generated) Python-wrapper code coverage.
Slightly.
parent b801d5d1
......@@ -133,7 +133,14 @@ const UUIDArray& Entity::relations() const
return this->m_relations;
}
Entity& Entity::appendRelation(const UUID& b)
int Entity::appendRelation(const UUID& b)
{
int reln = static_cast<int>(this->m_relations.size());
this->m_relations.push_back(b);
return reln;
}
Entity& Entity::pushRelation(const UUID& b)
{
this->m_relations.push_back(b);
return *this;
......
......@@ -43,7 +43,8 @@ public:
smtk::util::UUIDArray& relations();
const smtk::util::UUIDArray& relations() const;
Entity& appendRelation(const smtk::util::UUID& b);
int appendRelation(const smtk::util::UUID& b);
Entity& pushRelation(const smtk::util::UUID& b);
Entity& removeRelation(const smtk::util::UUID& b);
int findOrAppendRelation(const smtk::util::UUID& r);
......
set(smtkModelPythonTests
modelBodyCreate
modelBodyCursors
cursorTutorial
)
......
......@@ -26,11 +26,11 @@ if __name__ == '__main__':
u02 = store.addEntity(f2)
u03 = store.addEntity(f3)
u04 = store.addEntity(f4)
volume.appendRelation(u01).\
appendRelation(u02).\
appendRelation(u03).\
appendRelation(u04).\
appendRelation(model.entity())
volume.pushRelation(u01).\
pushRelation(u02).\
pushRelation(u03).\
pushRelation(u04).\
pushRelation(model.entity())
u00 = store.addEntity(volume)
# Now verify that the faces refer back to the volume:
status = False if store.findEntity(u01).relations()[0] == u00 else True
......
"""
Demonstrate model construction from within Python.
This construction technique is similar to how Bridge subclasses will create models.
Bridges assign UUIDs to model entities they transcribe as SMTK requests access to
the model entities. These UUIDs may be saved from previous sessions, so allowing
SMTK to assign a new, random UUID to a model entity being translated is not an option.
Instead, the Bridge mandates the UUID.
This example uses insertXXX() and setXXX() methods to create SMTK-model
entries with externally-provided UUIDs.
"""
import os
import smtk
if __name__ == '__main__':
import sys
status = 0
try:
store = smtk.model.Storage.create()
# Add some models to storage:
model = store.addModel(3, 3, 'Test Model')
# Create a model as if we were importing it (i.e., UUIDs already assigned).
# This tests the methods created for use by Bridge subclasses.
ugen = smtk.util.UUIDGenerator()
uids = [ugen.random() for x in range(50)]; # Generate 10 UUIDs
# Cells
volume = store.insertVolume(uids[0])
face1 = store.insertFace(uids[1])
face2 = store.insertFace(uids[2])
edge1 = store.insertEdge(uids[3])
edge2 = store.insertEdge(uids[4])
vert1 = store.insertVertex(uids[5])
vert2 = store.insertVertex(uids[6])
model.addCell(volume)
# Uses
# The volume is used once by the model
voluse = store.setVolumeUse(uids[7], volume)
# Each face is used once by the volume. Exterior face-uses are not included.
face1use = store.setFaceUse(uids[8], face1, 0, smtk.model.POSITIVE)
face2use = store.setFaceUse(uids[9], face2, 0, smtk.model.POSITIVE)
# Each edge is used twice (once by each face)
edge1use1 = store.setEdgeUse(uids[10], edge1, 0, smtk.model.POSITIVE)
edge2use1 = store.setEdgeUse(uids[11], edge2, 0, smtk.model.POSITIVE)
edge1use2 = store.setEdgeUse(uids[12], edge1, 0, smtk.model.NEGATIVE)
edge2use2 = store.setEdgeUse(uids[13], edge2, 0, smtk.model.NEGATIVE)
# Each vertex has a single connected component attached to it, and thus has a single sense.
vert1use = store.setVertexUse(uids[14], vert1, 0)
vert2use = store.setVertexUse(uids[15], vert2, 0)
# Shells
# First, we create the shells (indicating their parent cell-use)
shell1 = store.setShell(uids[16], voluse)
loop1 = store.setLoop(uids[17], face1use)
loop2 = store.setLoop(uids[18], face2use)
chain1 = store.setChain(uids[19], edge1use1)
chain2 = store.setChain(uids[20], edge2use1)
chain3 = store.setChain(uids[21], edge1use2)
chain4 = store.setChain(uids[22], edge2use2)
# Now we add child cell-uses to each shell:
shell1.addUse(face1use).addUse(face2use)
loop1.addUse(edge1use1).addUse(edge2use1)
loop2.addUse(edge1use2).addUse(edge2use2)
chain1.addUse(vert1use).addUse(vert2use)
chain2.addUse(vert2use).addUse(vert1use)
chain3.addUse(vert2use).addUse(vert1use)
chain4.addUse(vert1use).addUse(vert2use)
# Add "unoriented" cell-cell relationships
# Without these, boundaryEntities/bordantEntities will not work.
# assignDefaultNames needs bordantEntities in order to determine
# the owningModelEntity for naming...
store.findEntity(uids[0]).pushRelation(uids[1]).pushRelation(uids[2])
store.findEntity(uids[1]).pushRelation(uids[0]).pushRelation(uids[3])
store.findEntity(uids[2]).pushRelation(uids[0]).pushRelation(uids[4])
store.findEntity(uids[3]).pushRelation(uids[1]).pushRelation(uids[5])
store.findEntity(uids[4]).pushRelation(uids[2]).pushRelation(uids[6])
store.findEntity(uids[5]).pushRelation(uids[3]).pushRelation(uids[4])
store.findEntity(uids[6]).pushRelation(uids[4]).pushRelation(uids[3])
store.assignDefaultNames()
print smtk.model.ExportJSON.fromModel(store)
status = \
len(vert1.edges()) != 2 or \
any([vert not in vert1.edges() for vert in vert2.edges()]) or \
edge1use1.boundingShellEntity().entity() != loop1.entity() or \
edge1use2.boundingShellEntity().entity() != loop2.entity() or \
edge2use1.boundingShellEntity().entity() != loop1.entity() or \
edge2use2.boundingShellEntity().entity() != loop2.entity() or \
loop1.face().entity() != face1.entity() or \
loop2.face().entity() != face2.entity()
except Exception, ex:
print 'Exception:'
exc_type, exc_obj, exc_tb = sys.exc_info()
fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
print
print 'Exception: ', exc_type, fname, 'line', exc_tb.tb_lineno
print
print ex
print
status = True
sys.exit(0 if not status else 1)
......@@ -723,20 +723,15 @@ smtk::util::UUID Storage::findCreateOrReplaceCellUseOfSenseAndOrientation(
}
// Now add the use to the cell and the cell to the use:
smtk::util::UUIDArray::size_type useIdx = entity->relations().size();
entity->appendRelation(use->first);
smtk::util::UUIDArray::size_type cellIdx = use->second.relations().size();
use->second.appendRelation(cell);
this->arrangeEntity(
cell, HAS_USE,
Arrangement::CellHasUseWithIndexSenseAndOrientation(
static_cast<int>(useIdx), sense, orient),
entity->appendRelation(use->first), sense, orient),
arrIdx);
this->arrangeEntity(
use->first, HAS_CELL,
Arrangement::UseHasCellWithIndexAndSense(
static_cast<int>(cellIdx), sense));
use->second.appendRelation(cell), sense));
return use->first;
}
......@@ -811,6 +806,38 @@ smtk::util::UUID Storage::createIncludedShell(const smtk::util::UUID& useOrShell
return shell->first;
}
/** Add a shell to \a parentUseOrShell as an inclusion unless it already exists.
*
* Returns true when adding the shell was necessary.
* Returns false if either entity does not exist or the shell was already owned by the parent.
*/
bool Storage::findOrAddIncludedShell(
const smtk::util::UUID& parentUseOrShell,
const smtk::util::UUID& shellToInclude)
{
Entity* parEnt = this->findEntity(parentUseOrShell);
Entity* shlEnt = this->findEntity(shellToInclude);
if (!parEnt || !shlEnt)
{
return false;
}
int indexOfShell = this->findArrangementInvolvingEntity(
parentUseOrShell, INCLUDES, shellToInclude);
if (indexOfShell >= 0)
return false;
// Didn't find it. Add both forward and inverse relations.
this->arrangeEntity(parentUseOrShell, INCLUDES,
Arrangement::UseOrShellIncludesShellWithIndex(
parEnt->appendRelation(shellToInclude)));
this->arrangeEntity(shellToInclude, EMBEDDED_IN,
Arrangement::ShellEmbeddedInUseOrShellWithIndex(
shlEnt->appendRelation(parentUseOrShell)));
return true;
}
/**\brief Add a cell-use to a shell if it is not already contained in the shell.
*
* Note that cell-uses may have relations to shells of 2 different dimensions.
......@@ -1148,6 +1175,57 @@ Volume Storage::addVolume()
this->addEntityOfTypeAndDimension(CELL_ENTITY, 3));
}
/// Insert a VertexUse at the specified \a uid.
VertexUse Storage::insertVertexUse(const smtk::util::UUID& uid)
{
return VertexUse(
shared_from_this(),
this->setEntityOfTypeAndDimension(uid, USE_ENTITY, 0)->first);
}
/// Create a VertexUse with the specified \a uid and replace \a src's VertexUse.
VertexUse Storage::setVertexUse(const smtk::util::UUID& uid, const Vertex& src, int sense)
{
VertexUse vertUse = this->insertVertexUse(uid);
this->findCreateOrReplaceCellUseOfSenseAndOrientation(
src.entity(), sense, POSITIVE, uid);
return vertUse;
}
/// Insert a EdgeUse at the specified \a uid.
EdgeUse Storage::insertEdgeUse(const smtk::util::UUID& uid)
{
return EdgeUse(
shared_from_this(),
this->setEntityOfTypeAndDimension(uid, USE_ENTITY, 1)->first);
}
/// Create a EdgeUse with the specified \a uid and replace \a src's EdgeUse.
EdgeUse Storage::setEdgeUse(const smtk::util::UUID& uid, const Edge& src, int sense, Orientation o)
{
EdgeUse edgeUse = this->insertEdgeUse(uid);
this->findCreateOrReplaceCellUseOfSenseAndOrientation(
src.entity(), sense, o, uid);
return edgeUse;
}
/// Insert a FaceUse at the specified \a uid.
FaceUse Storage::insertFaceUse(const smtk::util::UUID& uid)
{
return FaceUse(
shared_from_this(),
this->setEntityOfTypeAndDimension(uid, USE_ENTITY, 2)->first);
}
/// Create a FaceUse with the specified \a uid and replace \a src's FaceUse.
FaceUse Storage::setFaceUse(const smtk::util::UUID& uid, const Face& src, int sense, Orientation o)
{
FaceUse faceUse = this->insertFaceUse(uid);
this->findCreateOrReplaceCellUseOfSenseAndOrientation(
src.entity(), sense, o, uid);
return faceUse;
}
/// Insert a VolumeUse at the specified \a uid.
VolumeUse Storage::insertVolumeUse(const smtk::util::UUID& uid)
{
......@@ -1245,6 +1323,81 @@ VolumeUse Storage::addVolumeUse(const Volume& src)
return VolumeUse(); // invalid volume use if source volume was invalid or from different storage.
}
/// Insert a Chain at the specified \a uid.
Chain Storage::insertChain(const smtk::util::UUID& uid)
{
return Chain(
shared_from_this(),
this->setEntityOfTypeAndDimension(uid, SHELL_ENTITY | DIMENSION_0 | DIMENSION_1, -1)->first);
}
/// Find or add a chain to storage with a relationship back to its owning edge-use.
Chain Storage::setChain(const smtk::util::UUID& uid, const EdgeUse& use)
{
Chain chain = this->insertChain(uid);
this->findOrAddIncludedShell(use.entity(), uid);
return chain;
}
/// Find or add a chain to storage with a relationship back to its owning chain.
Chain Storage::setChain(const smtk::util::UUID& uid, const Chain& parent)
{
Chain chain = this->insertChain(uid);
this->findOrAddIncludedShell(parent.entity(), uid);
return chain;
}
/// Insert a Loop at the specified \a uid.
Loop Storage::insertLoop(const smtk::util::UUID& uid)
{
return Loop(
shared_from_this(),
this->setEntityOfTypeAndDimension(uid, SHELL_ENTITY | DIMENSION_1 | DIMENSION_2, -1)->first);
}
/// Find or add a chain to storage with a relationship back to its owning face-use.
Loop Storage::setLoop(const smtk::util::UUID& uid, const FaceUse& use)
{
Loop loop = this->insertLoop(uid);
this->findOrAddIncludedShell(use.entity(), uid);
return loop;
}
/// Find or add a chain to storage with a relationship back to its owning loop.
Loop Storage::setLoop(const smtk::util::UUID& uid, const Loop& parent)
{
Loop loop = this->insertLoop(uid);
this->findOrAddIncludedShell(parent.entity(), uid);
return loop;
}
/// Insert a Shell at the specified \a uid.
Shell Storage::insertShell(const smtk::util::UUID& uid)
{
return Shell(
shared_from_this(),
this->setEntityOfTypeAndDimension(uid, SHELL_ENTITY | DIMENSION_2 | DIMENSION_3, -1)->first);
}
/// Find or add a chain to storage with a relationship back to its owning volume-use.
Shell Storage::setShell(const smtk::util::UUID& uid, const VolumeUse& use)
{
Shell shell = this->insertShell(uid);
this->findOrAddIncludedShell(use.entity(), uid);
return shell;
}
/// Find or add a chain to storage with a relationship back to its owning shell.
Shell Storage::setShell(const smtk::util::UUID& uid, const Shell& parent)
{
Shell shell = this->insertShell(uid);
this->findOrAddIncludedShell(parent.entity(), uid);
return shell;
}
/// Add a 0/1-d shell (a vertex chain) to storage (without any relationships)
Chain Storage::addChain()
{
......
......@@ -87,6 +87,7 @@ public:
smtk::util::UUIDs useOrShellIncludesShells(const smtk::util::UUID& cellUseOrShell) const;
smtk::util::UUID createIncludedShell(const smtk::util::UUID& cellUseOrShell);
bool findOrAddIncludedShell(const smtk::util::UUID& parentUseOrShell, const smtk::util::UUID& shellToInclude);
//bool shellHasUse(const smtk::util::UUID& shell, const smtk::util::UUID& use) const;
//smtk::util::UUIDs shellHasUses(const smtk::util::UUID& shell) const;
......@@ -110,14 +111,12 @@ public:
Face addFace();
Volume addVolume();
/*
VertexUse insertVertexUse(const smtk::util::UUID& uid);
VertexUse insertVertexUse(const smtk::util::UUID& uid, const Vertex& src, int sense);
VertexUse setVertexUse(const smtk::util::UUID& uid, const Vertex& src, int sense);
EdgeUse insertEdgeUse(const smtk::util::UUID& uid);
EdgeUse insertEdgeUse(const smtk::util::UUID& uid, const Edge& src, int sense, Orientation o);
EdgeUse setEdgeUse(const smtk::util::UUID& uid, const Edge& src, int sense, Orientation o);
FaceUse insertFaceUse(const smtk::util::UUID& uid);
FaceUse insertFaceUse(const smtk::util::UUID& uid, const Face& src, int sense, Orientation o);
*/
FaceUse setFaceUse(const smtk::util::UUID& uid, const Face& src, int sense, Orientation o);
VolumeUse insertVolumeUse(const smtk::util::UUID& uid);
VolumeUse setVolumeUse(const smtk::util::UUID& uid, const Volume& src);
......@@ -130,6 +129,16 @@ public:
VolumeUse addVolumeUse();
VolumeUse addVolumeUse(const Volume& src);
Chain insertChain(const smtk::util::UUID& uid);
Chain setChain(const smtk::util::UUID& uid, const EdgeUse& use);
Chain setChain(const smtk::util::UUID& uid, const Chain& parent);
Loop insertLoop(const smtk::util::UUID& uid);
Loop setLoop(const smtk::util::UUID& uid, const FaceUse& use);
Loop setLoop(const smtk::util::UUID& uid, const Loop& parent);
Shell insertShell(const smtk::util::UUID& uid);
Shell setShell(const smtk::util::UUID& uid, const VolumeUse& use);
Shell setShell(const smtk::util::UUID& uid, const Shell& parent);
Chain addChain();
Chain addChain(const EdgeUse&);
Chain addChain(const Chain&);
......
......@@ -25,7 +25,7 @@ Orientation UseEntity::orientation() const
{
// This is tricky. We currently only store the orientation with
// the cell, not the cell-use. So we must retrieve the particular
// arrangement on the cell pointing to this FaceUse and report
// arrangement on the cell pointing to this Use and report
// that arrangement's orientation.
// Find the cell for this use record.
......
......@@ -49,57 +49,57 @@ UUIDArray createTet(smtk::model::StoragePtr sm)
smtk::util::UUID uc05 = sm->insertCellOfDimension(0)->first;
smtk::util::UUID uc06 = sm->insertCellOfDimension(0)->first;
smtk::util::UUID uc07 = sm->insertEntity(Entity(CELL_ENTITY, 1).appendRelation(uc00).appendRelation(uc01))->first;
smtk::util::UUID uc08 = sm->insertEntity(Entity(CELL_ENTITY, 1).appendRelation(uc01).appendRelation(uc02))->first;
smtk::util::UUID uc09 = sm->insertEntity(Entity(CELL_ENTITY, 1).appendRelation(uc02).appendRelation(uc00))->first;
smtk::util::UUID uc10 = sm->insertEntity(Entity(CELL_ENTITY, 1).appendRelation(uc03).appendRelation(uc04))->first;
smtk::util::UUID uc11 = sm->insertEntity(Entity(CELL_ENTITY, 1).appendRelation(uc04).appendRelation(uc05))->first;
smtk::util::UUID uc12 = sm->insertEntity(Entity(CELL_ENTITY, 1).appendRelation(uc05).appendRelation(uc03))->first;
smtk::util::UUID uc13 = sm->insertEntity(Entity(CELL_ENTITY, 1).appendRelation(uc00).appendRelation(uc06))->first;
smtk::util::UUID uc14 = sm->insertEntity(Entity(CELL_ENTITY, 1).appendRelation(uc01).appendRelation(uc06))->first;
smtk::util::UUID uc15 = sm->insertEntity(Entity(CELL_ENTITY, 1).appendRelation(uc02).appendRelation(uc06))->first;
smtk::util::UUID uc07 = sm->insertEntity(Entity(CELL_ENTITY, 1).pushRelation(uc00).pushRelation(uc01))->first;
smtk::util::UUID uc08 = sm->insertEntity(Entity(CELL_ENTITY, 1).pushRelation(uc01).pushRelation(uc02))->first;
smtk::util::UUID uc09 = sm->insertEntity(Entity(CELL_ENTITY, 1).pushRelation(uc02).pushRelation(uc00))->first;
smtk::util::UUID uc10 = sm->insertEntity(Entity(CELL_ENTITY, 1).pushRelation(uc03).pushRelation(uc04))->first;
smtk::util::UUID uc11 = sm->insertEntity(Entity(CELL_ENTITY, 1).pushRelation(uc04).pushRelation(uc05))->first;
smtk::util::UUID uc12 = sm->insertEntity(Entity(CELL_ENTITY, 1).pushRelation(uc05).pushRelation(uc03))->first;
smtk::util::UUID uc13 = sm->insertEntity(Entity(CELL_ENTITY, 1).pushRelation(uc00).pushRelation(uc06))->first;
smtk::util::UUID uc14 = sm->insertEntity(Entity(CELL_ENTITY, 1).pushRelation(uc01).pushRelation(uc06))->first;
smtk::util::UUID uc15 = sm->insertEntity(Entity(CELL_ENTITY, 1).pushRelation(uc02).pushRelation(uc06))->first;
smtk::util::UUID uc16 = sm->insertEntity(
Entity(CELL_ENTITY, 2)
.appendRelation(uc07)
.appendRelation(uc08)
.appendRelation(uc09)
.appendRelation(uc10)
.appendRelation(uc11)
.appendRelation(uc12)
.pushRelation(uc07)
.pushRelation(uc08)
.pushRelation(uc09)
.pushRelation(uc10)
.pushRelation(uc11)
.pushRelation(uc12)
)->first;
smtk::util::UUID uc17 = sm->insertEntity(
Entity(CELL_ENTITY, 2)
.appendRelation(uc10)
.appendRelation(uc12)
.appendRelation(uc11)
.pushRelation(uc10)
.pushRelation(uc12)
.pushRelation(uc11)
)->first;
smtk::util::UUID uc18 = sm->insertEntity(
Entity(CELL_ENTITY, 2)
.appendRelation(uc07)
.appendRelation(uc13)
.appendRelation(uc14)
.pushRelation(uc07)
.pushRelation(uc13)
.pushRelation(uc14)
)->first;
smtk::util::UUID uc19 = sm->insertEntity(
Entity(CELL_ENTITY, 2)
.appendRelation(uc08)
.appendRelation(uc14)
.appendRelation(uc15)
.pushRelation(uc08)
.pushRelation(uc14)
.pushRelation(uc15)
)->first;
smtk::util::UUID uc20 = sm->insertEntity(
Entity(CELL_ENTITY, 2)
.appendRelation(uc09)
.appendRelation(uc15)
.appendRelation(uc13)
.pushRelation(uc09)
.pushRelation(uc15)
.pushRelation(uc13)
)->first;
smtk::util::UUID uc21 = sm->insertEntity(
Entity(CELL_ENTITY, 3)
.appendRelation(uc16)
.appendRelation(uc17)
.appendRelation(uc18)
.appendRelation(uc19)
.appendRelation(uc20))->first;
.pushRelation(uc16)
.pushRelation(uc17)
.pushRelation(uc18)
.pushRelation(uc19)
.pushRelation(uc20))->first;
sm->setTessellation(uc21, Tessellation()
.addCoords(x[0][0], x[0][1], x[0][2])
......
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