void BlobMesh::BuildMesh(TimeValue t) { //TODO: Implement the code to build the mesh representation of the object // using its parameter settings at the time passed. The plug-in should // use the data member mesh to store the built mesh. int numberOfNodes = pblock2->Count(pb_nodelist); float size, tension, renderCoarseness, viewCoarseness,coarseness; // Interval valid; pblock2->GetValue(pb_size,t,size,ivalid); pblock2->GetValue(pb_tension,t,tension,ivalid); if (tension < 0.011f) tension = 0.011f; if (tension > 1.0f) tension = 1.0f; pblock2->GetValue(pb_render,t,renderCoarseness,ivalid); pblock2->GetValue(pb_viewport,t,viewCoarseness,ivalid); BOOL autoCoarseness; pblock2->GetValue(pb_relativecoarseness,t,autoCoarseness,ivalid); BOOL largeDataSetOpt; pblock2->GetValue(pb_oldmetaballmethod,t,largeDataSetOpt,ivalid); BOOL useSoftSel; float minSize; pblock2->GetValue(pb_usesoftsel,t,useSoftSel,ivalid); pblock2->GetValue(pb_minsize,t,minSize,ivalid); if (inRender) coarseness = renderCoarseness; else coarseness = viewCoarseness; if (autoCoarseness) coarseness = size/coarseness; Tab<INode *> pfList; BOOL useAllPFEvents; pblock2->GetValue(pb_useallpf,0,useAllPFEvents,FOREVER); int pfCt = pblock2->Count(pb_pfeventlist); BOOL offInView; pblock2->GetValue(pb_offinview,0,offInView,FOREVER); for (int i = 0; i < pfCt; i++) { INode* node = NULL; pblock2->GetValue(pb_pfeventlist,0,node,FOREVER,i); if (node) pfList.Append(1,&node); } float thres = 0.6f; //need to get our tm if (selfNode == NULL) { MyEnumProc dep(true); DoEnumDependents(&dep); if (dep.Nodes.Count() > 0) selfNode = dep.Nodes[0]; } Matrix3 baseTM(1); if (selfNode != NULL) baseTM = Inverse(selfNode->GetObjectTM(t)); //loop throght the nodes if (!inRender) { if (offInView) numberOfNodes = 0; } std::vector<SphereData> data; data.reserve(500); for (int i = 0; i < numberOfNodes; i++) { INode* node = NULL; pblock2->GetValue(pb_nodelist,t,node,ivalid,i); if (node) { //get the nodes tm Matrix3 objectTM = node->GetObjectTM(t); Matrix3 toLocalSpace = objectTM*baseTM; ObjectState tos = node->EvalWorldState(t,TRUE); if (tos.obj->IsParticleSystem()) { SimpleParticle* pobj = NULL; IParticleObjectExt* epobj = NULL; pobj = static_cast<SimpleParticle*>( tos.obj->GetInterface(I_SIMPLEPARTICLEOBJ) ); if (pobj) { pobj->UpdateParticles(t, node); int count = pobj->parts.Count(); data.reserve(data.size() + count); float closest = 999999999.9f; SphereData d; for (int pid = 0; pid < count; pid++) { TimeValue age = pobj->ParticleAge(t,pid); TimeValue life = pobj->ParticleLife(t,pid); if (age != -1) { float psize = pobj->ParticleSize(t,pid); Point3 curval = pobj->parts.points[pid]; d.center = curval * baseTM; d.radius = psize; d.oradius = psize; d.rsquare = psize * psize; d.tover4 = tension * d.rsquare *d.rsquare ; data.push_back(d); } } } else { epobj = (IParticleObjectExt*) tos.obj->GetInterface(PARTICLEOBJECTEXT_INTERFACE); if (epobj) { epobj->UpdateParticles(node, t); int count = epobj->NumParticles(); data.reserve(data.size() + count); for (int pid = 0; pid < count; pid++) { TimeValue age = epobj->GetParticleAgeByIndex(pid); if (age!=-1) { INode *node = epobj->GetParticleGroup(pid); Point3 *curval = epobj->GetParticlePositionByIndex(pid); BOOL useParticle = TRUE; if (!useAllPFEvents) { useParticle = FALSE; for (int k = 0; k < pfList.Count(); k++) { if (node == pfList[k]) { useParticle = TRUE; k = pfList.Count(); } } } if ((curval) && (useParticle)) { float scale = epobj->GetParticleScaleByIndex(pid) ; float psize = scale; SphereData d; d.center = *curval*baseTM; d.radius = psize; d.oradius = psize; d.rsquare = psize * psize; d.tover4 = tension * d.rsquare *d.rsquare ; data.push_back(d); } } } } } } else if (tos.obj->IsShapeObject()) { PolyShape shape; ShapeObject *pathOb = (ShapeObject*)tos.obj; pathOb->MakePolyShape(t, shape); // first find out how many points there are: size_t num_points = 0; for (int i = 0; i < shape.numLines; i++) { PolyLine& line = shape.lines[i]; num_points += line.numPts; } data.reserve(data.size() + num_points); for (int i = 0; i < shape.numLines; i++) { PolyLine line = shape.lines[i]; for (int j = 0; j < line.numPts; j++) { SphereData d; float tsize = size; d.center = line.pts[j].p*toLocalSpace; d.radius = tsize; d.oradius = tsize; d.rsquare = tsize * tsize; d.tover4 = tension * d.rsquare *d.rsquare ; data.push_back(d); } } } else if (tos.obj->SuperClassID()==GEOMOBJECT_CLASS_ID) { SphereData d; BOOL converted = FALSE; TriObject *triObj = NULL; if(tos.obj->IsSubClassOf(triObjectClassID)) { triObj = (TriObject *)tos.obj; } // If it can convert to a TriObject, do it else if(tos.obj->CanConvertToType(triObjectClassID)) { triObj = (TriObject *)tos.obj->ConvertToType(t, triObjectClassID); converted = TRUE; } if (triObj != NULL) { Mesh* mesh = &triObj->GetMesh(); if (mesh) { int vcount = mesh->getNumVerts(); float *vsw = mesh->getVSelectionWeights (); BitArray vsel = mesh->VertSel(); data.reserve(data.size() + vcount); for (int j = 0; j < vcount; j++) { float tsize = size; if (useSoftSel) { tsize = 0.0f; if (vsw) { float v = 0.0f; if (vsel[j]) v = 1.0f; else { if (vsw) v = vsw[j]; } if (v == 0.0f) tsize = 0.0f; else { tsize = minSize + (size -minSize)*v; } } else { float v = 0.0f; if (vsel[j]) v = 1.0f; tsize = minSize + (size -minSize)*v; } } if (tsize != 0.0f) { d.center = mesh->getVert(j)*toLocalSpace; d.radius = tsize; d.oradius = tsize; d.rsquare = tsize * tsize; d.tover4 = tension * d.rsquare *d.rsquare ; data.push_back(d); } } } if (converted) triObj->DeleteThis(); } } else { SphereData d; d.center = Point3(0.0f,0.0f,0.0f)*toLocalSpace; d.radius = size; d.oradius = size; d.rsquare = size * size; d.tover4 = tension * d.rsquare *d.rsquare ; data.push_back(d); } } } if ((data.size() == 0) && (numberOfNodes==0)) { data.resize(1); data[0].center = Point3(0.0f,0.0f,0.0f); data[0].radius = size; data[0].oradius = size; data[0].rsquare = size * size; data[0].tover4 = tension * data[0].rsquare *data[0].rsquare ; } if (data.size() > 0) { int iRes = 1; if (!largeDataSetOpt) { MetaParticle oldBlob; iRes = oldBlob.CreatePodMetas(&data[0],(int)data.size(),&mesh,thres,coarseness); } else { MetaParticleFast blob; iRes = blob.CreatePodMetas(&data[0],(int)data.size(),&mesh,thres,coarseness); } // An out of memory error is the only reason iRes would be zero in either case if( (iRes == 0) && GetCOREInterface() ) GetCOREInterface()->DisplayTempPrompt(GetString(IDS_NOT_ENOUGH_MEM), 5000 ); } else { mesh.setNumFaces(0); mesh.setNumVerts(0); } mesh.InvalidateTopologyCache(); ivalid.Set(t,t); }