bool RandomFillFilter::applyFilter(QAction*, MeshDocument &md, RichParameterSet& par, vcg::CallBackPos* cb){ if(parametersAreNotCorrect(md, par)) return false; MeshSubFilter::initialize(md, par, cb); if(cb != 0) (*cb)(0, "Physics renderization of the scene started..."); MeshModel* container = par.getMesh("container"); MeshModel* filler = par.getMesh("filler"); int fillOffset = md.size(); float gravity[3] = {0.0f, par.getBool("useRandomVertices") ? 0.0f : -9.8f, 0.0f}; if(par.getBool("flipNormal")){ vcg::tri::Clean<CMeshO>::FlipMesh(container->cm); tri::UpdateNormals<CMeshO>::PerVertexNormalizedPerFace(container->cm); container->clearDataMask(MeshModel::MM_FACEFACETOPO | MeshModel::MM_FACEFLAGBORDER); } m_engine.clear(); m_engine.setGlobalForce(gravity); m_engine.setIterations(par.getInt("iterations")); m_engine.setMaxContacts(par.getInt("contacts")); m_engine.setBounciness(par.getFloat("bounciness")); m_engine.setFriction(par.getFloat("friction")); m_engine.registerTriMesh(*container, true); srand((unsigned)time(0)); vcg::tri::UpdatePosition<CMeshO>::Matrix(filler->cm, filler->cm.Tr); filler->cm.Tr.SetIdentity(); tri::Inertia<CMeshO> inertiaContainer, inertiaFiller; inertiaContainer.Compute(par.getMesh("container")->cm); inertiaFiller.Compute(par.getMesh("filler")->cm); int objects = abs(inertiaContainer.Mass()/inertiaFiller.Mass())*par.getFloat("factor"); filler->cm.Tr.SetColumn(3, - inertiaFiller.CenterOfMass()); //Restore old generated meshes int restoredMeshes = 0; for(int i = 0; i < md.size(); i++){ if(md.getMesh(i)->fileName.find("randomFillMesh") == 0){ m_engine.registerTriMesh(*md.getMesh(i)); restoredMeshes++; m_engine.integrate(1.0f/par.getInt("fps")); } } int frequency = 1 / par.getFloat("updateFrequency"); // To refactor when the right algorithm has be found if(par.getBool("useRandomVertices")){ for(int i = 0; i < objects; i++){ if(cb != 0) (*cb)(50.f*i/objects, "Computing..."); addRandomObject(md, filler, getRandomOrigin(par), restoredMeshes + i); m_engine.registerTriMesh(*md.getMesh(fillOffset++)); } for(int j = 0; j < par.getFloat("seconds") * par.getInt("fps"); j++){ if(cb != 0) (*cb)(50 + 48.f*j/(par.getFloat("seconds") * par.getInt("fps")), "Computing..."); m_engine.integrate(1.0f/par.getInt("fps")); } }else{ for(int i = 0; i < objects; i++){ if(cb != 0) (*cb)(98.f*i/objects, "Computing..."); addRandomObject(md, filler, inertiaContainer.CenterOfMass(), i); m_engine.registerTriMesh(*md.getMesh(fillOffset++)); if(i % frequency == 0) for(int j = 0; j < par.getFloat("seconds") * par.getInt("fps"); j++) m_engine.integrate(1.0f/par.getInt("fps")); } } m_engine.updateTransform(); filler->cm.Tr.SetIdentity(); m_currentFilterType = m_filterType; if(par.getBool("flipNormal")){ vcg::tri::Clean<CMeshO>::FlipMesh(container->cm); tri::UpdateNormals<CMeshO>::PerVertexNormalizedPerFace(container->cm); container->clearDataMask(MeshModel::MM_FACEFACETOPO | MeshModel::MM_FACEFLAGBORDER); } if(cb != 0) (*cb)(99, "Physics renderization of the scene completed..."); return true; }
static void parseMeshInfo(MeshModel* root, float curr_time) { _log("OBJECT_NODE_TAG"); enterChunk(); std::string name, inst; Vector pivot; Animation anim; unsigned short id = 65535, parent = 65535, flags1, flags2; Box box = Box(Vector(), Vector()); Vector box_centre; while (int chunk_id = nextChunk()) { switch (chunk_id) { case 0xb030: //NODE_ID in.sgetn((char*)&id, 2); _log("NODE_ID: " + itoa(id)); break; case 0xb010: //NODE_HDR name = parseString(); in.sgetn((char*)&flags1, 2); in.sgetn((char*)&flags2, 2); in.sgetn((char*)&parent, 2); _log("NODE_HDR: name=" + name + " parent=" + itoa(parent)); break; case 0xb011: //INSTANCE NAME inst = parseString(); _log("INSTANCE_NAME: " + inst); break; case 0xb013: //PIVOT in.sgetn((char*)&pivot, 12); if (conv) pivot = conv_tform * pivot; _log("PIVOT: " + ftoa(pivot.x) + "," + ftoa(pivot.y) + "," + ftoa(pivot.z)); break; case 0xb014: //BOUNDBOX in.sgetn((char*)&(box.a), 12); in.sgetn((char*)&(box.b), 12); box_centre = box.centre(); if (conv) box_centre = conv_tform * box_centre; _log("BOUNDBOX: min=" + ftoa(box.a.x) + "," + ftoa(box.a.y) + "," + ftoa(box.a.z) + " max=" + ftoa(box.b.x) + "," + ftoa(box.b.y) + "," + ftoa(box.b.z)); break; case 0xb020: //POS_TRACK_TAG case 0xb021: //ROT_TRACK_TAG case 0xb022: //SCALE_TRACK_TAG if (!collapse) parseAnimKeys(&anim, chunk_id); break; } } leaveChunk(); MeshModel* p = root; if (parent != 65535) { std::map<int, MeshModel*>::const_iterator it = id_map.find(parent); if (it == id_map.end()) return; p = it->second; } MeshModel* mesh = 0; if (name == "$$$DUMMY") { mesh = new MeshModel(); mesh->SetName(inst); mesh->SetParent(p); } else { std::map<std::string, MeshModel*>::const_iterator it = name_map.find(name); if (it == name_map.end()) return; mesh = it->second; name_map.erase(name); if (pivot != Vector()) { mesh->transform(-pivot); } Transform t = mesh->GetWorldTransform(); mesh->SetParent(p); mesh->SetWorldTransform(t); } mesh->setAnimation(anim); if (id != 65535) id_map[id] = mesh; }
bool BaseMeshIOPlugin::open(const QString &formatName, const QString &fileName, MeshModel &m, int& mask, const RichParameterSet &parlst, CallBackPos *cb, QWidget * /*parent*/) { bool normalsUpdated = false; // initializing mask mask = 0; // initializing progress bar status if (cb != NULL) (*cb)(0, "Loading..."); QString errorMsgFormat = "Error encountered while loading file:\n\"%1\"\n\nError details: %2"; //string filename = fileName.toUtf8().data(); string filename = QFile::encodeName(fileName).constData (); if (formatName.toUpper() == tr("PLY")) { tri::io::ImporterPLY<CMeshO>::LoadMask(filename.c_str(), mask); // small patch to allow the loading of per wedge color into faces. if(mask & tri::io::Mask::IOM_WEDGCOLOR) mask |= tri::io::Mask::IOM_FACECOLOR; m.Enable(mask); int result = tri::io::ImporterPLY<CMeshO>::Open(m.cm, filename.c_str(), mask, cb); if (result != 0) // all the importers return 0 on success { if(tri::io::ImporterPLY<CMeshO>::ErrorCritical(result) ) { errorMessage = errorMsgFormat.arg(fileName, tri::io::ImporterPLY<CMeshO>::ErrorMsg(result)); return false; } } } else if (formatName.toUpper() == tr("STL")) { int result = tri::io::ImporterSTL<CMeshO>::Open(m.cm, filename.c_str(), cb); if (result != 0) // all the importers return 0 on success { errorMessage = errorMsgFormat.arg(fileName, tri::io::ImporterSTL<CMeshO>::ErrorMsg(result)); return false; } } else if( (formatName.toUpper() == tr("OBJ")) || (formatName.toUpper() == tr("QOBJ")) ) { tri::io::ImporterOBJ<CMeshO>::Info oi; oi.cb = cb; if (!tri::io::ImporterOBJ<CMeshO>::LoadMask(filename.c_str(), oi)) return false; m.Enable(oi.mask); int result = tri::io::ImporterOBJ<CMeshO>::Open(m.cm, filename.c_str(), oi); if (result != tri::io::ImporterOBJ<CMeshO>::E_NOERROR) { if (result & tri::io::ImporterOBJ<CMeshO>::E_NON_CRITICAL_ERROR) errorMessage = errorMsgFormat.arg(fileName, tri::io::ImporterOBJ<CMeshO>::ErrorMsg(result)); else { errorMessage = errorMsgFormat.arg(fileName, tri::io::ImporterOBJ<CMeshO>::ErrorMsg(result)); return false; } } if(oi.mask & tri::io::Mask::IOM_WEDGNORMAL) normalsUpdated = true; m.Enable(oi.mask); if(m.hasDataMask(MeshModel::MM_POLYGONAL)) qDebug("Mesh is Polygonal!"); mask = oi.mask; } else if (formatName.toUpper() == tr("PTX")) { tri::io::ImporterPTX<CMeshO>::Info importparams; importparams.meshnum = parlst.findParameter("meshindex")->val->getInt(); importparams.anglecull =parlst.findParameter("anglecull")->val->getBool(); importparams.angle = parlst.findParameter("angle")->val->getFloat(); importparams.savecolor = parlst.findParameter("usecolor")->val->getBool(); importparams.pointcull = parlst.findParameter("pointcull")->val->getBool(); importparams.pointsonly = parlst.findParameter("pointsonly")->val->getBool(); importparams.switchside = parlst.findParameter("switchside")->val->getBool(); importparams.flipfaces = parlst.findParameter("flipfaces")->val->getBool(); // if color, add to mesh if(importparams.savecolor) importparams.mask |= tri::io::Mask::IOM_VERTCOLOR; // reflectance is stored in quality importparams.mask |= tri::io::Mask::IOM_VERTQUALITY; m.Enable(importparams.mask); int result = tri::io::ImporterPTX<CMeshO>::Open(m.cm, filename.c_str(), importparams, cb); if (result == 1) { errorMessage = errorMsgFormat.arg(fileName, tri::io::ImporterPTX<CMeshO>::ErrorMsg(result)); return false; } // update mask mask = importparams.mask; } else if (formatName.toUpper() == tr("OFF")) { int loadMask; if (!tri::io::ImporterOFF<CMeshO>::LoadMask(filename.c_str(),loadMask)) return false; m.Enable(loadMask); int result = tri::io::ImporterOFF<CMeshO>::Open(m.cm, filename.c_str(), mask, cb); if (result != 0) // OFFCodes enum is protected { errorMessage = errorMsgFormat.arg(fileName, tri::io::ImporterOFF<CMeshO>::ErrorMsg(result)); return false; } } else if (formatName.toUpper() == tr("VMI")) { int loadMask; if (!tri::io::ImporterVMI<CMeshO>::LoadMask(filename.c_str(),loadMask)) return false; m.Enable(loadMask); int result = tri::io::ImporterVMI<CMeshO>::Open(m.cm, filename.c_str(), mask, cb); if (result != 0) { errorMessage = errorMsgFormat.arg(fileName, tri::io::ImporterOFF<CMeshO>::ErrorMsg(result)); return false; } } else { assert(0); // Unknown File type return false; } // verify if texture files are present QString missingTextureFilesMsg = "The following texture files were not found:\n"; bool someTextureNotFound = false; for ( unsigned textureIdx = 0; textureIdx < m.cm.textures.size(); ++textureIdx) { if (!QFile::exists(m.cm.textures[textureIdx].c_str())) { missingTextureFilesMsg.append("\n"); missingTextureFilesMsg.append(m.cm.textures[textureIdx].c_str()); someTextureNotFound = true; } } if (someTextureNotFound) Log("Missing texture files: %s", qPrintable(missingTextureFilesMsg)); if (cb != NULL) (*cb)(99, "Done"); return true; }
bool BaseMeshIOPlugin::save(const QString &formatName,const QString &fileName, MeshModel &m, const int mask, const RichParameterSet & par, CallBackPos *cb, QWidget */*parent*/) { QString errorMsgFormat = "Error encountered while exportering file %1:\n%2"; string filename = QFile::encodeName(fileName).constData (); //string filename = fileName.toUtf8().data(); string ex = formatName.toUtf8().data(); bool binaryFlag = false; if(formatName.toUpper() == tr("STL") || formatName.toUpper() == tr("PLY")) binaryFlag = par.findParameter("Binary")->val->getBool(); if(formatName.toUpper() == tr("PLY")) { int result = tri::io::ExporterPLY<CMeshO>::Save(m.cm,filename.c_str(),mask,binaryFlag,cb); if(result!=0) { errorMessage = errorMsgFormat.arg(fileName, tri::io::ExporterPLY<CMeshO>::ErrorMsg(result)); return false; } return true; } if(formatName.toUpper() == tr("STL")) { int result = tri::io::ExporterSTL<CMeshO>::Save(m.cm,filename.c_str(),binaryFlag); if(result!=0) { errorMessage = errorMsgFormat.arg(fileName, tri::io::ExporterSTL<CMeshO>::ErrorMsg(result)); return false; } return true; } if(formatName.toUpper() == tr("WRL")) { int result = tri::io::ExporterWRL<CMeshO>::Save(m.cm,filename.c_str(),mask,cb); if(result!=0) { errorMessage = errorMsgFormat.arg(fileName, tri::io::ExporterWRL<CMeshO>::ErrorMsg(result)); return false; } return true; } if( formatName.toUpper() == tr("OFF")) { if(mask && tri::io::Mask::IOM_BITPOLYGONAL) m.updateDataMask(MeshModel::MM_FACEFACETOPO); int result = tri::io::Exporter<CMeshO>::Save(m.cm,filename.c_str(),mask,cb); if(result!=0) { errorMessage = errorMsgFormat.arg(fileName, tri::io::Exporter<CMeshO>::ErrorMsg(result)); return false; } return true; } if( formatName.toUpper() == tr("DXF") || formatName.toUpper() == tr("OBJ") ) { int result = tri::io::Exporter<CMeshO>::Save(m.cm,filename.c_str(),mask,cb); if(result!=0) { errorMessage = errorMsgFormat.arg(fileName, tri::io::Exporter<CMeshO>::ErrorMsg(result)); return false; } return true; } assert(0); // unknown format return false; }
void EditPointPlugin::Decorate(MeshModel &m, GLArea * gla, QPainter *p) { this->RealTimeLog("Point Selection",m.shortName(), "<table>" "<tr><td width=50> Hop Thr:</td><td width=100 align=right><b >%8.3f </b></td><td><i> (Wheel to change it)</i> </td></tr>" "<tr><td> Radius: </td><td width=70 align=right><b> %8.3f </b></td><td><i> (Drag or Alt+Wheel to change it)</i></td></tr>" "</table>",this->maxHop,this->dist); /* When the user first click we have to find the point under the mouse pointer. At the same time we need to compute the Dijkstra algorithm over the knn-graph in order to find the distance between the selected point and the others. */ if(haveToPick) { glPushMatrix(); glMultMatrix(m.cm.Tr); vector<CMeshO::VertexPointer> NewSel; GLPickTri<CMeshO>::PickVert(cur.x(), gla->height() - cur.y(), m.cm, NewSel); if(NewSel.size() > 0) { startingVertex = NewSel.front(); tri::ComponentFinder<CMeshO>::Dijkstra(m.cm, *startingVertex, K, this->maxHop, this->NotReachableVector); ComponentVector.push_back(startingVertex); } haveToPick = false; glPopMatrix(); } /* When at least a point is selected we need to draw the selection */ if (startingVertex != NULL) { glPushMatrix(); glMultMatrix(m.cm.Tr); glPushAttrib(GL_ENABLE_BIT ); glDisable(GL_LIGHTING); glDisable(GL_TEXTURE_2D); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glDepthRange (0.0, 0.9999); glDepthFunc(GL_LEQUAL); glPointSize(6.f); tri::UpdateSelection<CMeshO>::VertexClear(m.cm); /* In OldComponentVector we find all the points selected until the last click of the mouse. The other points are saved in ComponentVector. With two different structures for old and new selection we can add or subtract one from each other. */ switch (composingSelMode) { case SMSub: for(vector<CMeshO::VertexPointer>::iterator vi = OldComponentVector.begin(); vi != OldComponentVector.end(); ++vi) { (*vi)->SetS(); } for(vector<CMeshO::VertexPointer>::iterator vi = ComponentVector.begin(); vi != ComponentVector.end(); ++vi) { (*vi)->ClearS(); } break; case SMAdd: for(vector<CMeshO::VertexPointer>::iterator vi = OldComponentVector.begin(); vi != OldComponentVector.end(); ++vi) { (*vi)->SetS(); } for(vector<CMeshO::VertexPointer>::iterator vi = ComponentVector.begin(); vi != ComponentVector.end(); ++vi) { (*vi)->SetS(); } break; case SMClear: for(vector<CMeshO::VertexPointer>::iterator vi = ComponentVector.begin(); vi != ComponentVector.end(); ++vi) { (*vi)->SetS(); } break; } /* The actual selection is drawn in red (instead of the automatic drawing of selected vertex of MeshLab) */ glBegin(GL_POINTS); glColor4f(1,0,0,.5f); for (CMeshO::VertexIterator vi = m.cm.vert.begin(); vi != m.cm.vert.end(); vi++) { if (vi->IsS()) glVertex(vi->cP()); } glEnd(); /* Borders points are drawn in yellow. */ glBegin(GL_POINTS); glColor4f(1,1,0,.5f); for(vector<CMeshO::VertexPointer>::iterator vi = BorderVector.begin(); vi != BorderVector.end(); ++vi) { if ((*vi)->IsS()) glVertex((*vi)->cP()); } glEnd(); /* If the "fitting plane" plugin is selected we draw a light blue circle to visualize the actual plane found by the algorithm (and the fitted points). */ if (editType == SELECT_FITTING_PLANE_MODE) { fittingCircle.Clear(); vcg::tri::OrientedDisk<CMeshO>(fittingCircle, 192, fittingPlane.Projection(startingVertex->cP()), fittingPlane.Direction(), this->fittingRadius); glBegin(GL_TRIANGLE_FAN); glColor4f(0.69,0.93,0.93,.7f); CMeshO::VertexIterator vi; for (vi = fittingCircle.vert.begin(); vi != fittingCircle.vert.end(); vi++) { glVertex(vi->cP()); } vi = fittingCircle.vert.begin(); vi++; glVertex(vi->cP()); glEnd(); } glPopAttrib(); glPopMatrix(); } }
bool FilterIsoParametrization::applyFilter(QAction *filter, MeshDocument& md, RichParameterSet & par, vcg::CallBackPos *cb) { MeshModel* m = md.mm(); //get current mesh from document CMeshO *mesh=&m->cm; switch(ID(filter)) { case ISOP_PARAM : { int targetAbstractMinFaceNum = par.getInt("targetAbstractMinFaceNum"); int targetAbstractMaxFaceNum = par.getInt("targetAbstractMaxFaceNum"); int convergenceSpeed = par.getInt("convergenceSpeed"); int stopCriteria=par.getEnum("stopCriteria"); bool doublestep=par.getBool("DoubleStep"); IsoParametrizator Parametrizator; m->updateDataMask(MeshModel::MM_FACEFACETOPO); m->updateDataMask(MeshModel::MM_VERTQUALITY); // needed to store patch index bool isTXTenabled=m->hasDataMask(MeshModel::MM_VERTTEXCOORD); if (!isTXTenabled) m->updateDataMask(MeshModel::MM_VERTTEXCOORD); bool isVMarkenabled=m->hasDataMask(MeshModel::MM_VERTMARK); if (!isVMarkenabled) m->updateDataMask(MeshModel::MM_VERTMARK); bool isFMarkenabled=m->hasDataMask(MeshModel::MM_FACEMARK); if (!isFMarkenabled) m->updateDataMask(MeshModel::MM_FACEMARK); bool isVColorenabled=m->hasDataMask(MeshModel::MM_VERTCOLOR); if (!isVColorenabled) m->updateDataMask(MeshModel::MM_VERTCOLOR); bool isFColorenabled=m->hasDataMask(MeshModel::MM_FACECOLOR); if (!isFColorenabled) m->updateDataMask(MeshModel::MM_FACECOLOR); int tolerance = targetAbstractMaxFaceNum-targetAbstractMinFaceNum; switch (stopCriteria) { case 0: Parametrizator.SetParameters(cb,targetAbstractMinFaceNum,tolerance,IsoParametrizator::SM_Euristic,convergenceSpeed); break; case 1: Parametrizator.SetParameters(cb,targetAbstractMinFaceNum,tolerance,IsoParametrizator::SM_Corr,convergenceSpeed); break; case 2: Parametrizator.SetParameters(cb,targetAbstractMinFaceNum,tolerance,IsoParametrizator::SM_Reg,convergenceSpeed); break; case 3: Parametrizator.SetParameters(cb,targetAbstractMinFaceNum,tolerance,IsoParametrizator::SM_L2,convergenceSpeed); break; default: Parametrizator.SetParameters(cb,targetAbstractMinFaceNum,tolerance,IsoParametrizator::SM_Euristic,convergenceSpeed); break; } tri::ParamEdgeCollapseParameter pecp; IsoParametrizator::ReturnCode ret=Parametrizator.Parametrize<CMeshO>(mesh,pecp,doublestep); if (ret==IsoParametrizator::Done) { Parametrizator.PrintAttributes(); float aggregate,L2; int n_faces; Parametrizator.getValues(aggregate,L2,n_faces); Log("Num Faces of Abstract Domain: %d, One way stretch efficiency: %.4f, Area+Angle Distorsion %.4f ",n_faces,L2,aggregate*100.f); } else { if (!isTXTenabled) m->clearDataMask(MeshModel::MM_VERTTEXCOORD); if (!isFMarkenabled) m->clearDataMask(MeshModel::MM_FACEMARK); if (!isVMarkenabled) m->clearDataMask(MeshModel::MM_VERTMARK); if (!isVColorenabled) m->clearDataMask(MeshModel::MM_VERTCOLOR); if (!isFColorenabled) m->clearDataMask(MeshModel::MM_FACECOLOR); switch(ret) { case IsoParametrizator::MultiComponent: this->errorMessage="non possible parameterization because of multi componet mesh"; return false; case IsoParametrizator::NonSizeCons: this->errorMessage="non possible parameterization because of non size consistent mesh"; return false; case IsoParametrizator::NonManifoldE: this->errorMessage="non possible parameterization because of non manifold edges"; return false; case IsoParametrizator::NonManifoldV: this->errorMessage="non possible parameterization because of non manifold vertices"; return false; case IsoParametrizator::NonWatertigh: this->errorMessage="non possible parameterization because of non watertight mesh"; return false; case IsoParametrizator::FailParam: this->errorMessage="non possible parameterization cause one of the following reasons:\n Topologycal noise \n Too Low resolution mesh \n Too Bad triangulation \n"; return false; default: this->errorMessage="unknown error"; return false; } } // At this point we are sure that everithing went ok so we can allocate surely the abstract AbstractMesh *abs_mesh = new AbstractMesh(); ParamMesh *para_mesh = new ParamMesh(); Parametrizator.ExportMeshes(*para_mesh,*abs_mesh); CMeshO::PerMeshAttributeHandle<IsoParametrization> isoPHandle; isoPHandle=tri::Allocator<CMeshO>::AddPerMeshAttribute<IsoParametrization>(*mesh,"isoparametrization"); bool isOK=isoPHandle().Init(abs_mesh,para_mesh); ///copy back to original mesh isoPHandle().CopyParametrization<CMeshO>(mesh); if (!isOK) { this->errorMessage="Problems gathering parameterization \n"; return false; } if (!isVMarkenabled) m->clearDataMask(MeshModel::MM_VERTMARK); if (!isFMarkenabled) m->clearDataMask(MeshModel::MM_FACEMARK); return true; } case ISOP_REMESHING : { CMeshO::PerMeshAttributeHandle<IsoParametrization> isoPHandle = tri::Allocator<CMeshO>::FindPerMeshAttribute<IsoParametrization>(*mesh,"isoparametrization"); bool b=tri::Allocator<CMeshO>::IsValidHandle<IsoParametrization>(*mesh,isoPHandle); if (!b) { this->errorMessage="You must compute the Base domain before remeshing. Use the Isoparametrization command."; return false; } int SamplingRate=par.getInt("SamplingRate"); if (!SamplingRate>2) { this->errorMessage="Sampling rate must be >1"; return false; } MeshModel* mm=md.addNewMesh("","Re-meshed"); CMeshO *rem=&mm->cm; DiamSampler DiamSampl; DiamSampl.Init(&isoPHandle()); bool done=DiamSampl.SamplePos(SamplingRate); assert(done); DiamSampl.GetMesh<CMeshO>(*rem); int n_diamonds,inFace,inEdge,inStar,n_merged; DiamSampl.getResData(n_diamonds,inFace,inEdge,inStar,n_merged); Log("INTERPOLATION DOMAINS"); Log("In Face: %d \n",inFace); Log("In Diamond: %d \n",inEdge); Log("In Star: %d \n",inStar); Log("Merged %d vertices\n",n_merged); mm->updateDataMask(MeshModel::MM_FACEFACETOPO); mm->updateDataMask(MeshModel::MM_VERTFACETOPO); PrintStats(rem); tri::UpdateNormal<CMeshO>::PerFace(*rem); return true; } case ISOP_DIAMPARAM : { CMeshO::PerMeshAttributeHandle<IsoParametrization> isoPHandle = tri::Allocator<CMeshO>::FindPerMeshAttribute<IsoParametrization>(*mesh,"isoparametrization"); bool b=tri::Allocator<CMeshO>::IsValidHandle<IsoParametrization>(*mesh,isoPHandle); if (!b) { this->errorMessage="You must compute the Base domain before remeshing. Use the Isoparametrization command."; return false; } float border_size=par.getDynamicFloat("BorderSize"); MeshModel* mm=md.addNewMesh("","Diam-Parameterized"); mm->updateDataMask(MeshModel::MM_WEDGTEXCOORD); mm->updateDataMask(MeshModel::MM_VERTCOLOR); CMeshO *rem=&mm->cm; DiamondParametrizator DiaPara; DiaPara.Init(&isoPHandle()); DiaPara.SetCoordinates<CMeshO>(*rem,border_size); tri::UpdateNormal<CMeshO>::PerFace(*rem); return true; } case ISOP_LOAD : { QString AbsName = par.getString("AbsName"); m->updateDataMask(MeshModel::MM_WEDGTEXCOORD); m->updateDataMask(MeshModel::MM_VERTTEXCOORD); m->updateDataMask(MeshModel::MM_FACECOLOR); m->updateDataMask(MeshModel::MM_VERTQUALITY); m->updateDataMask(MeshModel::MM_FACEMARK); if(!QFile(m->fullName()).exists()) { this->errorMessage="File not exists"; return false; } CMeshO::PerMeshAttributeHandle<IsoParametrization> isoPHandle = tri::Allocator<CMeshO>::FindPerMeshAttribute<IsoParametrization>(*mesh,"isoparametrization"); bool b=tri::Allocator<CMeshO>::IsValidHandle<IsoParametrization>(*mesh,isoPHandle); if (!b) isoPHandle=tri::Allocator<CMeshO>::AddPerMeshAttribute<IsoParametrization>(*mesh,"isoparametrization"); QByteArray ba = AbsName.toLatin1(); char *path=ba.data(); AbstractMesh *abs_mesh = new AbstractMesh(); ParamMesh *para_mesh = new ParamMesh(); bool Done=isoPHandle().LoadBaseDomain<CMeshO>(path,mesh,para_mesh,abs_mesh,true); if (!Done) { this->errorMessage="Abstract domain doesnt fit well with the parametrized mesh"; delete para_mesh; delete abs_mesh; return false; } return true; } case ISOP_SAVE : { m->updateDataMask(MeshModel::MM_VERTQUALITY); CMeshO::PerMeshAttributeHandle<IsoParametrization> isoPHandle = tri::Allocator<CMeshO>::FindPerMeshAttribute<IsoParametrization>(*mesh,"isoparametrization"); bool b=tri::Allocator<CMeshO>::IsValidHandle<IsoParametrization>(*mesh,isoPHandle); if (!b) { this->errorMessage="You must compute the Base domain before remeshing. Use the Isoparametrization command."; return false; } /*QString Qpath=m->fullName();*/ QString AbsName = par.getString("AbsName"); QByteArray ba = AbsName.toLatin1(); char *path=ba.data(); isoPHandle().SaveBaseDomain(path); return true; } case ISOP_TRANSFER: { MeshModel *mmtrg = par.getMesh("targetMesh"); MeshModel *mmsrc = par.getMesh("targetMesh"); CMeshO *trgMesh=&mmtrg->cm; CMeshO *srcMesh=&mmsrc->cm; CMeshO::PerMeshAttributeHandle<IsoParametrization> isoPHandle = tri::Allocator<CMeshO>::FindPerMeshAttribute<IsoParametrization>(*mesh,"isoparametrization"); bool b=tri::Allocator<CMeshO>::IsValidHandle<IsoParametrization>(*srcMesh,isoPHandle); if (!b) { this->errorMessage="Your source mesh must have the abstract isoparametrization. Use the Isoparametrization command."; return false; } IsoTransfer IsoTr; AbstractMesh *abs_mesh = isoPHandle().AbsMesh(); ParamMesh *para_mesh = isoPHandle().ParaMesh(); mmtrg->updateDataMask(MeshModel::MM_WEDGTEXCOORD); mmtrg->updateDataMask(MeshModel::MM_VERTTEXCOORD); mmtrg->updateDataMask(MeshModel::MM_FACECOLOR); mmtrg->updateDataMask(MeshModel::MM_VERTQUALITY); mmtrg->updateDataMask(MeshModel::MM_FACEMARK); IsoTr.Transfer<CMeshO>(isoPHandle(),*trgMesh); isoPHandle().Clear(); tri::Allocator<CMeshO>::DeletePerMeshAttribute(*srcMesh,isoPHandle); isoPHandle=tri::Allocator<CMeshO>::AddPerMeshAttribute<IsoParametrization>(*trgMesh,"isoparametrization"); isoPHandle().AbsMesh()=abs_mesh; isoPHandle().SetParamMesh<CMeshO>(trgMesh,para_mesh); return true; } } return false; }