diff --git a/smtk/bridge/discrete/Session.cxx b/smtk/bridge/discrete/Session.cxx index 007f8df543..df31056f76 100644 --- a/smtk/bridge/discrete/Session.cxx +++ b/smtk/bridge/discrete/Session.cxx @@ -827,6 +827,14 @@ smtk::model::Group Session::addMaterialToManager( { // Add material relations and arrangements translated |= smtk::model::SESSION_ENTITY_ARRANGED; + if (material->GetNumberOfAssociations(vtkModelRegionType)) + { // Add regions to material + this->addEntities(result, material->NewIterator(vtkModelRegionType), AddEntityToGroupHelper(), relDepth - 1); + } + else if(material->GetNumberOfAssociations(vtkModelFaceType)) + { // Add faces to material group + this->addEntities(result, material->NewIterator(vtkModelFaceType), AddEntityToGroupHelper(), relDepth - 1); + } } // Add material properties: @@ -1091,20 +1099,24 @@ smtk::model::Volume Session::addVolumeToManager( smtk::model::ManagerPtr mgr, int relDepth) { - if (refVolume && !mgr->findEntity(uid, false)) + if (refVolume) { - smtk::model::Volume result(mgr->insertVolume(uid)); - smtk::model::SessionInfoBits translated = smtk::model::SESSION_NOTHING; - if (relDepth >= 0) + smtk::model::Volume result; + // if there is a Volume already for refVolume, return it; otherwise, create one + if(mgr->findEntity(uid, false)) + result = smtk::model::Volume(mgr, uid); + else { - // Add refVolume relations and arrangements - this->addEntities(result, refVolume->NewAdjacentModelFaceIterator(), AddRawRelationHelper(), relDepth - 1); - this->addEntities(result, refVolume->NewIterator(vtkModelShellUseType), AddVolumeUseToVolumeHelper(), relDepth - 1); + result = mgr->insertVolume(uid); + if (relDepth >= 0) + { + // Add refVolume relations and arrangements + this->addEntities(result, refVolume->NewAdjacentModelFaceIterator(), AddRawRelationHelper(), relDepth - 1); + this->addEntities(result, refVolume->NewIterator(vtkModelShellUseType), AddVolumeUseToVolumeHelper(), relDepth - 1); + } + this->addProperties(result, refVolume); } - this->addProperties(result, refVolume); - translated |= smtk::model::SESSION_PROPERTIES; - return result; } return smtk::model::Volume(); diff --git a/smtk/bridge/discrete/operators/EntityGroupOperator.cxx b/smtk/bridge/discrete/operators/EntityGroupOperator.cxx index 087142736d..821dc34567 100644 --- a/smtk/bridge/discrete/operators/EntityGroupOperator.cxx +++ b/smtk/bridge/discrete/operators/EntityGroupOperator.cxx @@ -23,7 +23,9 @@ #include "vtkDiscreteModel.h" #include "vtkDiscreteModelEntityGroup.h" #include "vtkDiscreteModelWrapper.h" +#include "vtkIdList.h" #include "vtkModel.h" +#include "vtkModelMaterial.h" #include "EntityGroupOperator_xml.h" @@ -64,15 +66,37 @@ bool EntityGroupOperator::ableToOperate() std::string optype = optypeItem->value(); // if(optype == "Create") //only need model; if(optype == "Remove") - able2Op = this->fetchCMBCellId("remove cell group") >= 0; + able2Op = this->fetchCMBCell("remove cell group") != NULL; else if(optype == "Modify") - able2Op = this->fetchCMBCellId("modify cell group") >= 0 && ( - this->fetchCMBCellId("cell to add") >= 0 || - this->fetchCMBCellId("cell to remove") >= 0 ); + able2Op = this->fetchCMBCell("modify cell group") != NULL && ( + this->fetchCMBCell("cell to add") || + this->fetchCMBCell("cell to remove") ); return able2Op; } +int EntityGroupOperator::createBoundaryGroup(vtkDiscreteModelWrapper* modelWrapper) +{ + int entType = modelWrapper->GetModel()->GetModelDimension() == 3 ? + vtkModelFaceType : + (modelWrapper->GetModel()->GetModelDimension() == 2 ? + vtkModelEdgeType : -1); + if (entType == -1) + return -1; + + this->m_opBoundary->SetBuildEnityType(entType); + this->m_opBoundary->Build(modelWrapper); + int grpId = this->m_opBoundary->GetBuiltModelEntityGroupId(); + return grpId; +} + +int EntityGroupOperator::createDomainSet(vtkDiscreteModelWrapper* modelWrapper) +{ + this->m_opDomain->Build(modelWrapper); + int dsId = this->m_opDomain->GetBuiltMaterialId(); + return dsId; +} + OperatorResult EntityGroupOperator::operateInternal() { smtk::model::ManagerPtr pstore = this->manager(); @@ -84,6 +108,7 @@ OperatorResult EntityGroupOperator::operateInternal() opsession->findModelEntity(model.entity()); bool ok = false; smtk::model::Group bgroup; + smtk::model::EntityRefArray modGrps; smtk::model::EntityRefs grpsRemoved; // Translate SMTK inputs into CMB inputs smtk::attribute::StringItem::Ptr optypeItem = @@ -91,20 +116,30 @@ OperatorResult EntityGroupOperator::operateInternal() std::string optype = optypeItem->value(); if(optype == "Create") //only need model { - int gType = this->specification()->findInt("entity type")->value(); + int gType = this->specification()->findInt("group type")->value(); std::string gName = this->specification()->findString("group name")->value(); - int entType = gType==0 ? vtkModelFaceType : - (gType==1 ? vtkModelEdgeType : vtkModelVertexType); - this->m_op->SetBuildEnityType(entType); - this->m_op->Build(modelWrapper); - int grpId = this->m_op->GetBuiltModelEntityGroupId(); + + int grpId = -1; + if(gType == 0) // boundary group + grpId = this->createBoundaryGroup(modelWrapper); + else if(gType == 1) // domain set + grpId = this->createDomainSet(modelWrapper); ok = grpId>=0; + if(ok) { - BitFlags mask = entType==vtkModelFaceType ? smtk::model::FACE : - (entType==vtkModelEdgeType ? smtk::model::EDGE : smtk::model::VERTEX); - vtkDiscreteModelEntityGroup* grp = dynamic_cast( - modelWrapper->GetModelEntity(vtkDiscreteModelEntityGroupType, grpId)); + BitFlags mask = + // Boundary group, 3d => Face group; 2d => edge group. + (gType == 0) ? + (modelWrapper->GetModel()->GetModelDimension() == 3 ? + smtk::model::FACE : smtk::model::EDGE) : + // Domain set, 3d => volume group; 2d => face group. + (modelWrapper->GetModel()->GetModelDimension() == 3 ? + smtk::model::VOLUME : smtk::model::FACE); + int groupType = gType == 0 ? + vtkDiscreteModelEntityGroupType : vtkModelMaterialType; + vtkModelEntity* grp = + modelWrapper->GetModelEntity(groupType, grpId); smtk::common::UUID grpUUID = opsession->findOrSetEntityUUID(grp); //bgroup = opsession->addGroupToManager(grpUUID, grp, pstore, 0); // The group itself should be added too @@ -115,6 +150,7 @@ OperatorResult EntityGroupOperator::operateInternal() bgroup.setName(gName); // Add group to model's relationship model.addGroup(bgroup); + modGrps.push_back(bgroup); std::cout << "new group: " << bgroup.name() << " id: " << grpUUID.toString() << "\n"; } } @@ -124,74 +160,155 @@ OperatorResult EntityGroupOperator::operateInternal() this->specification()->findModelEntity("remove cell group"); for(std::size_t idx=0; idxnumberOfValues(); idx++) { - int grpid = this->fetchCMBCellId(remgrpItem, idx); - if(grpid >= 0) + vtkModelEntity* modEntity = this->fetchCMBCell(remgrpItem, idx); + if(!modEntity) + continue; + if(modEntity->GetType() == vtkModelMaterialType) { - this->m_op->SetId(grpid); - this->m_op->Destroy(modelWrapper); - ok = this->m_op->GetDestroySucceeded(); - if(ok) - { - // get rid of the group from manager - smtk::model::EntityRef grpRem = remgrpItem->value(idx); - model.removeGroup(grpRem.as()); - pstore->erase(grpRem); - std::cout << "Removed " << grpRem.name() << " to " << model.name() << "\n"; - grpsRemoved.insert(grpRem); - } + this->m_opDomain->SetId(modEntity->GetUniquePersistentId()); + this->m_opDomain->Destroy(modelWrapper); + ok = this->m_opDomain->GetDestroySucceeded(); + } + else if(modEntity->GetType() == vtkDiscreteModelEntityGroupType) + { + this->m_opBoundary->SetId(modEntity->GetUniquePersistentId()); + this->m_opBoundary->Destroy(modelWrapper); + ok = this->m_opBoundary->GetDestroySucceeded(); + } + if(ok) + { + // get rid of the group from manager + smtk::model::EntityRef grpRem = remgrpItem->value(idx); + model.removeGroup(grpRem.as()); + pstore->erase(grpRem); + std::cout << "Removed " << grpRem.name() << " to " << model.name() << "\n"; + grpsRemoved.insert(grpRem); } } - } else if(optype == "Modify") { - int grpId = this->fetchCMBCellId("modify cell group"); - this->m_op->SetId(grpId); - smtk::attribute::ModelEntityItemPtr entItem = - this->specification()->findModelEntity("cell to add"); - for(std::size_t idx=0; idxnumberOfValues(); idx++) + vtkModelEntity* grpEntity = this->fetchCMBCell("modify cell group"); + if(grpEntity && (vtkModelMaterial::SafeDownCast(grpEntity) || + vtkDiscreteModelEntityGroup::SafeDownCast(grpEntity))) { - int cmbid = this->fetchCMBCellId(entItem, idx); - if(cmbid >= 0) - this->m_op->AddModelEntity(cmbid); - } + vtkModelMaterial* grpDS = vtkModelMaterial::SafeDownCast(grpEntity); + vtkDiscreteModelEntityGroup* grpBC = vtkDiscreteModelEntityGroup::SafeDownCast(grpEntity); + if(grpDS) + { + this->m_opDomain->ClearGeometricEntitiesToAdd(); + this->m_opDomain->ClearGeometricEntitiesToRemove(); + this->m_opDomain->SetId(grpEntity->GetUniquePersistentId()); + } + else if(grpBC) + { + this->m_opBoundary->ClearEntitiesToAdd(); + this->m_opBoundary->ClearEntitiesToRemove(); + this->m_opBoundary->SetId(grpEntity->GetUniquePersistentId()); + } + smtk::attribute::ModelEntityItemPtr entItem = + this->specification()->findModelEntity("cell to add"); + for(std::size_t idx=0; idxnumberOfValues(); idx++) + { + vtkModelEntity* modEntity = this->fetchCMBCell(entItem, idx); + if(!modEntity) + continue; + if(grpDS) + this->m_opDomain->AddModelGeometricEntity(modEntity->GetUniquePersistentId()); + else if(grpBC) + this->m_opBoundary->AddModelEntity(modEntity->GetUniquePersistentId()); + } - entItem = this->specification()->findModelEntity("cell to remove"); - for(std::size_t idx=0; idxnumberOfValues(); idx++) - { - int cmbid = this->fetchCMBCellId(entItem, idx); - if(cmbid >= 0) - this->m_op->RemoveModelEntity(cmbid); - } - this->m_op->Operate(modelWrapper); - ok = this->m_op->GetOperateSucceeded(); - if(ok) - { - vtkDiscreteModelEntityGroup* grp = dynamic_cast( - modelWrapper->GetModelEntity(vtkDiscreteModelEntityGroupType, grpId)); - // get rid of the group from manager - smtk::model::EntityRef grpC = - this->specification()->findModelEntity("modify cell group")->value(); - smtk::model::Group tmpGrp = grpC.as(); - BitFlags mask = tmpGrp.membershipMask(); - std::string gName = tmpGrp.name(); - model.removeGroup(tmpGrp); - pstore->erase(grpC); - -// bgroup = opsession->addGroupToManager(grpC.entity(), grp, pstore, true); - smtk::common::UUID grpUUID = opsession->findOrSetEntityUUID(grp); - // The group itself should be added too - grpC = opsession->addCMBEntityToManager( - grpUUID, grp, pstore, 1); - bgroup = grpC.as(); - bgroup.setMembershipMask(mask); - bgroup.setName(gName); + entItem = this->specification()->findModelEntity("cell to remove"); + for(std::size_t idx=0; idxnumberOfValues(); idx++) + { + vtkModelEntity* modEntity = this->fetchCMBCell(entItem, idx); + if(!modEntity) + continue; + if(grpDS) + this->m_opDomain->RemoveModelGeometricEntity(modEntity->GetUniquePersistentId()); + else if(grpBC) + this->m_opBoundary->RemoveModelEntity(modEntity->GetUniquePersistentId()); + } - // Add group to model's relationship - model.addGroup(bgroup); + if(grpDS) + { + this->m_opDomain->Operate(modelWrapper); + ok = this->m_opDomain->GetOperateSucceeded(); + } + else if(grpBC) + { + this->m_opBoundary->Operate(modelWrapper); + ok = this->m_opBoundary->GetOperateSucceeded(); + } - std::cout << "Modified " << grpC.name() << " in " << model.name() << "\n"; + if(ok) + { + // get rid of the group from manager + smtk::model::EntityRef grpC = + this->specification()->findModelEntity("modify cell group")->value(); + smtk::model::Group tmpGrp = grpC.as(); + + BitFlags mask = tmpGrp.membershipMask(); + std::string gName = tmpGrp.name(); + model.removeGroup(tmpGrp); + pstore->erase(grpC); + + smtk::common::UUID grpUUID = opsession->findOrSetEntityUUID(grpEntity); + // The group itself should be added too + grpC = opsession->addCMBEntityToManager( + grpUUID, grpEntity, pstore, 1); + bgroup = grpC.as(); + bgroup.setMembershipMask(mask); + bgroup.setName(gName); + + // Add group to model's relationship + model.addGroup(bgroup); + modGrps.push_back(bgroup); + + // if we are dealing with domain set, the entities can only belong + // to one vtkModelMaterial, and the vtkMaterialOperator will remove + // the relationship to previous materials from input entities. + // Therefore, we need to put the previous materials in "modified" + // item in result. + if(grpDS) + { + vtkIdList* prevMaterials = this->m_opDomain-> + GetPreviousMaterialsOfGeometricEntities(); + for(int i=0; iGetNumberOfIds();i++) + { + vtkModelEntity* matEntity = modelWrapper->GetModelEntity( + vtkModelMaterialType, prevMaterials->GetId(i)); + smtk::common::UUID prevGrpId = opsession->findOrSetEntityUUID(matEntity); + smtk::model::EntityRef prevGrpRef(pstore, prevGrpId); + smtk::model::Group prevGrp = prevGrpRef.as(); + if(!prevGrp.isValid()) + continue; + + BitFlags prevMask = prevGrp.membershipMask(); + std::string prevName = prevGrp.name(); + model.removeGroup(prevGrp); + pstore->erase(prevGrp); + + prevGrpId = opsession->findOrSetEntityUUID(matEntity); + // The group itself should be added too + smtk::model::EntityRef grpPrev = opsession->addCMBEntityToManager( + prevGrpId, matEntity, pstore, 1); + smtk::model::Group tmpgroup = grpPrev.as(); + tmpgroup.setMembershipMask(prevMask); + tmpgroup.setName(prevName); + + // Add group to model's relationship + model.addGroup(tmpgroup); + modGrps.push_back(tmpgroup); + + } + } + + std::cout << "Modified " << grpC.name() << " in " << model.name() << "\n"; + } } + } OperatorResult result = @@ -205,8 +322,8 @@ OperatorResult EntityGroupOperator::operateInternal() // Return the created or modified group. if(optype == "Create") this->addEntityToResult(result, bgroup, CREATED); - else if(optype == "Modify") - this->addEntityToResult(result, bgroup, MODIFIED); + else if(optype == "Modify" && modGrps.size() > 0) + this->addEntitiesToResult(result, modGrps, MODIFIED); } if(optype == "Remove" && grpsRemoved.size() > 0) { @@ -231,30 +348,24 @@ Session* EntityGroupOperator::discreteSession() const return dynamic_cast(this->session()); } -int EntityGroupOperator::fetchCMBCellId(const std::string& pname) const +vtkModelEntity* EntityGroupOperator::fetchCMBCell(const std::string& pname) const { vtkModelItem* item = this->discreteSession()->entityForUUID( this->specification()->findModelEntity(pname)->value().entity()); vtkModelEntity* cell = dynamic_cast(item); - if (cell) - return cell->GetUniquePersistentId(); - - return -1; + return cell; } -int EntityGroupOperator::fetchCMBCellId( +vtkModelEntity* EntityGroupOperator::fetchCMBCell( const smtk::attribute::ModelEntityItemPtr& entItem, int idx ) const { vtkModelItem* item = this->discreteSession()->entityForUUID(entItem->value(idx).entity()); vtkModelEntity* cell = dynamic_cast(item); - if (cell) - return cell->GetUniquePersistentId(); - - return -1; + return cell; } } // namespace discrete diff --git a/smtk/bridge/discrete/operators/EntityGroupOperator.h b/smtk/bridge/discrete/operators/EntityGroupOperator.h index e61b7f1fd9..f46b064433 100644 --- a/smtk/bridge/discrete/operators/EntityGroupOperator.h +++ b/smtk/bridge/discrete/operators/EntityGroupOperator.h @@ -14,6 +14,7 @@ #include "smtk/bridge/discrete/discreteSessionExports.h" #include "smtk/model/Operator.h" #include "vtkModelEntityGroupOperator.h" +#include "vtkMaterialOperator.h" #include "vtkNew.h" namespace smtk { @@ -43,11 +44,14 @@ class SMTKDISCRETESESSION_EXPORT EntityGroupOperator : public smtk::model::Opera EntityGroupOperator(); virtual smtk::model::OperatorResult operateInternal(); Session* discreteSession() const; - int fetchCMBCellId(const std::string& parameterName) const; - int fetchCMBCellId( + vtkModelEntity* fetchCMBCell(const std::string& parameterName) const; + vtkModelEntity* fetchCMBCell( const smtk::attribute::ModelEntityItemPtr&, int idx ) const; + int createBoundaryGroup(vtkDiscreteModelWrapper* modelWrapper); + int createDomainSet(vtkDiscreteModelWrapper* modelWrapper); - vtkNew m_op; + vtkNew m_opBoundary; + vtkNew m_opDomain; }; } // namespace discrete diff --git a/smtk/bridge/discrete/operators/EntityGroupOperator.sbt b/smtk/bridge/discrete/operators/EntityGroupOperator.sbt index 7e14abd3f9..446cb5480a 100644 --- a/smtk/bridge/discrete/operators/EntityGroupOperator.sbt +++ b/smtk/bridge/discrete/operators/EntityGroupOperator.sbt @@ -22,17 +22,19 @@ group --> - face|edge|vertex + volume|face|edge - face|edge|vertex + volume|face|edge - - EnityType that new built group will contain + + Group type for the discrete model kernel: + Boundary group (face or edge) is not partitioned, meaning each entity can belong to multiple boundary groups; + Domain group (volume or face) is partitioned, meaning each entity will only belong to one domain group. + - 0 - 1 - 2 + 0 + 1 @@ -44,8 +46,8 @@ Create + group type group name - entity type