void GetRandPlane(Box3f &bb, Plane3f &plane) { Point3f planeCenter = bb.Center(); Point3f planeDir = Point3f(-0.5f+float(rand())/RAND_MAX,-0.5f+float(rand())/RAND_MAX,-0.5f+float(rand())/RAND_MAX); planeDir.Normalize(); plane.Init(planeCenter+planeDir*0.3f*bb.Diag()*float(rand())/RAND_MAX,planeDir); }
int main( int argc, char **argv ) { if(argc<2) { printf("Usage trimesh_base <meshfilename.ply>\n"); return -1; } MyMesh m,em,cm,full; if(tri::io::ImporterPLY<MyMesh>::Open(m,argv[1])!=0) { printf("Error reading file %s\n",argv[1]); exit(0); } tri::UpdateFlags<MyMesh>::FaceBorderFromFF(m); tri::UpdateNormals<MyMesh>::PerVertexNormalized(m); tri::UpdateBounding<MyMesh>::Box(m); printf("Input mesh vn:%i fn:%i\n",m.vn,m.fn); printf( "Mesh has %i vert and %i faces\n", m.vn, m.fn ); srand(time(0)); Plane3f slicingPlane; Point3f planeCenter = m.bbox.Center(); for(int i=0;i<10;++i) { cm.Clear(); em.Clear(); Point3f planeDir = Point3f(-0.5f+float(rand())/RAND_MAX,-0.5f+float(rand())/RAND_MAX,-0.5f+float(rand())/RAND_MAX); planeDir.Normalize(); printf("slicing dir %5.2f %5.2f %5.2f\n",planeDir[0],planeDir[1],planeDir[2]); slicingPlane.Init(planeCenter+planeDir*0.3f*m.bbox.Diag()*float(rand())/RAND_MAX,planeDir); vcg::IntersectionPlaneMesh<MyMesh, MyMesh, float>(m, slicingPlane, em ); tri::Clean<MyMesh>::RemoveDuplicateVertex(em); vcg::tri::CapEdgeMesh(em,cm); printf(" edge mesh vn %5i en %5i fn %5i\n",em.vn,em.en,em.fn); printf("sliced mesh vn %5i en %5i fn %5i\n",cm.vn,cm.en,cm.fn); tri::Append<MyMesh,MyMesh>::Mesh(full,cm); } tri::io::ExporterPLY<MyMesh>::Save(full,"out.ply",false); return 0; }
bool ExtraFilter_SlicePlugin::applyFilter(QAction *filter, MeshDocument &m, RichParameterSet &parlst, vcg::CallBackPos *cb) { vcg::tri::UpdateBounding<CMeshO>::Box(m.mm()->cm); switch(ID(filter)) { case FP_WAFFLE_SLICE : { MeshModel* base = m.mm(); CMeshO &cmBase = base->cm; Box3f &bbox = m.mm()->cm.bbox; if (tri::Clean<CMeshO>::CountNonManifoldEdgeFF(cmBase)>0 || (tri::Clean<CMeshO>::CountNonManifoldVertexFF(cmBase,false) != 0)) { Log("Mesh is not two manifold, cannot apply filter"); return false; } if(parlst.getFloat("spacing") >= 1) { Log("the selected distance between the planes is greater than 1. The filter had no effect"); return false; } Point3f planeAxis(0,0,0); Axis axis = (Axis) parlst.getEnum("planeAxis"); planeAxis[axis] = 1.0f; float length = parlst.getFloat("length"); bool hideBase = parlst.getBool("hideBase"); bool hideEdge = parlst.getBool("hideEdge"); bool hidePlanes = parlst.getBool("hidePlanes"); bool hideExtrudes = parlst.getBool("hideExtrudes"); // set common SVG Properties const float maxdim=m.mm()->cm.bbox.Dim()[m.mm()->cm.bbox.MaxDim()]; Point3f sizeCm=m.mm()->cm.bbox.Dim()*(length/maxdim); // to check for dimensions with custom axis Axis axisOrthog, axisJoint; Point2f sizeCmOrth; switch(axis) { case X: { axisOrthog = (Axis) Succ<X>::value; axisJoint = (Axis) Succ<Succ<X>::value>::value; pr.sizeCm = Point2f(sizeCm[1],sizeCm[2]); sizeCmOrth.X()=sizeCm[0]; sizeCmOrth.Y()=sizeCm[2]; } break; case Y: { axisOrthog = (Axis) Succ<Y>::value; axisJoint = (Axis) Succ<Succ<Y>::value>::value; pr.sizeCm = Point2f(sizeCm[0],sizeCm[2]); sizeCmOrth.X()=sizeCm[0]; sizeCmOrth.Y()=sizeCm[1]; } break; case Z: { axisOrthog = (Axis) Succ<Z>::value; axisJoint = (Axis) Succ<Succ<Z>::value>::value; pr.sizeCm = Point2f(sizeCm[0],sizeCm[1]); sizeCmOrth.X()=sizeCm[1]; sizeCmOrth.Y()=sizeCm[2]; } break; } Log("sizecm %fx%f",pr.sizeCm[0],pr.sizeCm[1]); vector<CMeshO*> ev; const float planeDist = maxdim * parlst.getFloat("spacing"); const int planeNum = (planeDist == 0) ? 1 : ( ((bbox.Dim()*planeAxis)/planeDist)+1 ); //evito la divisione per 0 const float lengthDiag = bbox.Diag()/2.0; Segment2f lati[3]; //the rectangle is made up of three segments, the fourth side is ignored, so I never use it const float eps =planeDist*parlst.getFloat("eps"); float epsTmp; float start; int rectNum; if(parlst.getFloat("eps") < 1) { start = - (planeNum/2) * planeDist; //I have to go back from the center of half the length epsTmp = eps/2.0; generateRectSeg(0, epsTmp, bbox.Diag()*2, lati); rectNum = planeNum; } else { start = 0; epsTmp = bbox.Diag(); generateRectSeg(0, bbox.Diag()*2, bbox.Diag()*2, lati); rectNum = 1; Log("thickness is greater than 1: the extrusions will overlap"); } float planeOffset = parlst.getFloat("planeOffset"); pr.lineWidthPt=200; pr.scale=2/maxdim; pr.numCol=(int)(max((int)sqrt(planeNum*1.0f),2)+1); pr.numRow=(int)(planeNum*1.0f/pr.numCol)+1; pr.projDir = planeAxis; pr.projCenter = m.mm()->cm.bbox.Center(); pr.enumeration = true; MeshModel* cap, *cap2, *extr; QString layername; for(int pl = 0; pl < 2; ++pl) { // Log("################## PLANE %i", pl); Plane3f slicingPlane; Point3f planeCenter = bbox.Center() + planeAxis*planeOffset*lengthDiag; int numAdd = 0; // int i=4; //if I want to apply only the plan number i I decomment this variable and comment the cycle for(int i = 0; i < planeNum; ++i) //cropping the plans { // Log("######## LAYER %i", i); planeCenter[axis] = start + planeDist*i;; slicingPlane.Init(planeCenter,planeAxis); layername.sprintf("EdgeMesh_%d_%d",pl,numAdd); cap= m.addNewMesh("",qPrintable(layername)); vcg::IntersectionPlaneMesh<CMeshO, CMeshO, float>(base->cm, slicingPlane, cap->cm ); tri::Clean<CMeshO>::RemoveDuplicateVertex(cap->cm); if(cap->cm.edge.size()>= 3) { Incastri temp; // int j=1; //if I want to apply only the rectangle number j I decomment this variable and comment the cycle for(int j = 0; j <rectNum ; ++j) //clipping the rectangles { // Log("#### RECTANGLE %i", j); float newDist = start + planeDist*j; modifyOnY(lati, newDist+epsTmp, newDist-epsTmp); temp = subtraction(cap->cm, lati, axis, axisOrthog, axisJoint, planeCenter[axis]); if(temp == NOT_PLANE) {Log("ATTENTION! The IntersectionPlaneMesh did not return a plane silhouette in the current plane!"); m.delMesh(cap); break;} if(temp== NOT_SAGOME) {Log("ATTENTION! The IntersectionPlaneMesh did not return a simple closed silhouette for the plane %i, on axis %i",i, pl); m.delMesh(cap); break;} } if(temp > NOT_SAGOME) { ev.push_back(&(cap->cm)); //add the silhouette to those for export to SVG layername.sprintf("CappedSlice_%d_%d",pl,numAdd); //add the silhouettes converted in mesh cap2= m.addNewMesh("",qPrintable(layername)); tri::CapEdgeMesh(cap->cm, cap2->cm); layername.sprintf("Extruded_%d_%d",pl,numAdd++); //add the mesh extruded extr= m.addNewMesh("",qPrintable(layername)); cap2->updateDataMask(MeshModel::MM_FACEFACETOPO); extr->updateDataMask(MeshModel::MM_FACEFACETOPO); tri::UpdateTopology<CMeshO>::FaceFace(cap2->cm); tri::ExtrudeBoundary<CMeshO>(cap2->cm,extr->cm,eps,planeAxis); if(hideEdge) cap->visible =false; if(hidePlanes) cap2->visible =false; if(hideExtrudes) extr->visible =false; } }else m.delMesh(cap); //if the intersection does not exist I reject the result } QString fname;//= parlst.getSaveFileName("filename"); if(fname=="") fname.sprintf("Slice_%d.svg",pl); if (!fname.endsWith(".svg")) fname+=".svg"; tri::io::ExporterSVG<CMeshO>::Save(ev, fname.toStdString().c_str(), pr); ev.clear(); planeAxis[axis] = 0.0f; planeAxis[axisOrthog] = 1.0f; flipOnX(lati); pr.sizeCm = sizeCmOrth; pr.projDir = planeAxis; Axis aSwap = axis; axis = axisOrthog; axisOrthog = aSwap; } if(hideEdge) cap->visible =false; if(hidePlanes) cap2->visible =false; if(hideExtrudes) extr->visible =false; if(hideBase) base->visible =false; if(hideBase) base->visible =false; } break; } return true; }