BaseObject *Objectify::GetVirtualObjects(BaseObject *op, HierarchyHelp *hh) { BaseDocument *doc = op->GetDocument(); BaseContainer *data = op->GetDataInstance(); BaseObject* obj = (BaseObject*)data->GetLink(CTT_OBJECT_LINK,doc,Obase); LONG crntFrame = doc->GetTime().GetFrame(doc->GetFps()); if (!obj) return NULL; if (obj->GetType() != Ospline){ return NULL; } // start new list op->NewDependenceList(); // check cache for validity and check master object for changes Bool dirty = op->CheckCache(hh) || op->IsDirty(DIRTYFLAGS_DATA); // if child list has been modified if (!dirty) dirty = !op->CompareDependenceList(); // mark child objects as processed op->TouchDependenceList(); dirty = dirty || (prevFrame != crntFrame); prevFrame = crntFrame; // if no change has been detected, return original cache if (!dirty) return op->GetCache(hh); SplineObject* spline = (SplineObject*) obj; AutoAlloc<SplineHelp> splineHelp; StatusSetText("Collecting points"); float positioAlongSpline = data->GetReal(POSITION_ALONG_SPLINE,0.5); positioAlongSpline /= 10000.0f; positioAlongSpline = positioAlongSpline > 1.0 ? 1.0: positioAlongSpline; positioAlongSpline = positioAlongSpline < 0.0 ? 0.0: positioAlongSpline; cout<<positioAlongSpline<<endl; vector<vector<float> > points; for (LONG i = 0; i < spline->GetSegmentCount(); i++){ Vector p = spline->GetSplinePoint(positioAlongSpline, i); vector<float> point; point.push_back(p.x); point.push_back(p.y); point.push_back(p.z); points.push_back(point); } StatusSetText("Collected "+LongToString(points.size())+" points"); ksearchNeighbors= data->GetLong(TRIANGULATION_MAX_NEIGHBORS, 100); gp3SearchRadius = data->GetReal(TRIANGULATION_MAX_SEARCH_RADIUS,30.); gp3MaxNeighbors = data->GetLong(KSEARCH_NEIGHBORS, 20); gp3Mu = data->GetReal(KSEARCH_MU, 0.5); vector<vector<float> > surfacePoints; vector<vector<int> > triIndxs; StatusSetBar(0); StatusSetText("Triangulating"); bool useMls = data->GetBool(USE_MLS, false); tri.computeSurface(points, surfacePoints, triIndxs, ksearchNeighbors, gp3SearchRadius, gp3MaxNeighbors, gp3Mu, useMls); StatusSetBar(100); StatusSetText("Got "+LongToString(triIndxs.size())+" triangles"); if (triIndxs.size() == 0){ return NULL; } PolygonObject* myPoly = PolygonObject::Alloc(surfacePoints.size(),triIndxs.size()); Vector* ppoints = myPoly->GetPointW(); vector<float> sp; for (int t = 0; t < surfacePoints.size()-2; t += 3) { sp = surfacePoints[t]; ppoints[t+0] = Vector(sp[0],sp[1],sp[2]); sp = surfacePoints[t+1]; ppoints[t+1] = Vector(sp[0],sp[1],sp[2]); sp = surfacePoints[t+2]; ppoints[t+2] = Vector(sp[0],sp[1],sp[2]); } for (int t = 0; t < triIndxs.size(); t ++) { myPoly->GetPolygonW()[t] = CPolygon(triIndxs[t][0], triIndxs[t][1], triIndxs[t][2], triIndxs[t][2]); } StatusClear(); myPoly->Message(MSG_UPDATE); return ToPoly(myPoly); BaseThread* bt=hh->GetThread(); BaseObject* main = BaseObject::Alloc(Onull); SplineObject* emptySpline = SplineObject::Alloc(0, SPLINETYPE_LINEAR); ModelingCommandData mcd; mcd.doc = doc; mcd.op = emptySpline; if(!SendModelingCommand(MCOMMAND_JOIN, mcd)){ return NULL; } Error: return NULL; }
// build a single polygonal atom object static PolygonObject *BuildPolyHull(PolygonObject *op, const Matrix &ml, Real srad, Real crad, LONG sub, Real lod, Neighbor *n, BaseThread *bt) { BaseContainer bc,cc; LONG spcnt,svcnt,cpcnt,cvcnt,poff,voff,i,j,a=0,b=0,side; const Vector *spadr=NULL,*cpadr=NULL; Vector *rpadr=NULL; Vector off,pa,pb; const CPolygon *svadr=NULL,*cvadr=NULL; CPolygon *rvadr=NULL; UVWTag *suvw =NULL,*cuvw =NULL,*ruvw =NULL; const Vector *padr = op->GetPointR(); const CPolygon *vadr = op->GetPolygonR(); LONG pcnt = op->GetPointCount(); LONG vcnt = op->GetPolygonCount(); PolyInfo *pli = NULL; Bool ok=FALSE; Matrix m; UVWHandle suvwptr,duvwptr; // set sphere default values bc.SetReal(PRIM_SPHERE_RAD,srad); bc.SetReal(PRIM_SPHERE_SUB,sub); // set cylinder default values (cylinders are a special case of cone objects) cc.SetReal(PRIM_CYLINDER_RADIUS,crad); cc.SetReal(PRIM_CYLINDER_HEIGHT,1.0); cc.SetLong(PRIM_CYLINDER_CAPS,FALSE); cc.SetLong(PRIM_CYLINDER_HSUB,1); cc.SetLong(PRIM_CYLINDER_SEG,sub); cc.SetReal(PRIM_AXIS,4); // generate both primitives PolygonObject *sphere=(PolygonObject*)GeneratePrimitive(NULL,Osphere,bc,lod,FALSE,bt),*pp=NULL; PolygonObject *cyl=(PolygonObject*)GeneratePrimitive(NULL,Ocylinder,cc,lod,FALSE,bt); if (!sphere || !cyl) goto Error; spcnt = sphere->GetPointCount(); svcnt = sphere->GetPolygonCount(); spadr = sphere->GetPointR(); svadr = sphere->GetPolygonR(); suvw = (UVWTag*)sphere->GetTag(Tuvw); cpcnt = cyl->GetPointCount(); cvcnt = cyl->GetPolygonCount(); cpadr = cyl->GetPointR(); cvadr = cyl->GetPolygonR(); cuvw = (UVWTag*)cyl->GetTag(Tuvw); // allocate main object pp=PolygonObject::Alloc(spcnt*pcnt+cpcnt*n->GetEdgeCount(),svcnt*pcnt+cvcnt*n->GetEdgeCount()); if (!pp) goto Error; // add phong tag if (!pp->MakeTag(Tphong)) goto Error; // add UVW tag ruvw=(UVWTag*)pp->MakeVariableTag(Tuvw,pp->GetPolygonCount()); if (!ruvw) goto Error; // copy sphere geometry for each point rpadr = pp->GetPointW(); rvadr = pp->GetPolygonW(); poff = 0; voff = 0; suvwptr = suvw->GetDataAddressR(); duvwptr = ruvw->GetDataAddressW(); for (i=0; i<pcnt; i++) { // test every 256th time if there has been a user break, delete object in this case if (!(i&255) && bt && bt->TestBreak()) goto Error; off=padr[i]*ml; for (j=0; j<spcnt; j++) rpadr[poff+j] = off + spadr[j]; for (j=0; j<svcnt; j++) { rvadr[voff+j] = CPolygon(svadr[j].a+poff,svadr[j].b+poff,svadr[j].c+poff,svadr[j].d+poff); ruvw->Copy(duvwptr,voff+j,suvwptr,j); } poff+=spcnt; voff+=svcnt; } // copy cylinder geometry for each edge suvwptr = cuvw->GetDataAddressR(); duvwptr = ruvw->GetDataAddressW(); for (i=0; i<vcnt; i++) { pli = n->GetPolyInfo(i); // test every 256th time if there has been a user break, delete object in this case if (!(i&255) && bt && bt->TestBreak()) goto Error; for (side=0; side<4; side++) { // only proceed if edge has not already been processed // and edge really exists (for triangles side 2 from c..d does not exist as c==d) if (pli->mark[side] || side==2 && vadr[i].c==vadr[i].d) continue; switch (side) { case 0: a=vadr[i].a; b=vadr[i].b; break; case 1: a=vadr[i].b; b=vadr[i].c; break; case 2: a=vadr[i].c; b=vadr[i].d; break; case 3: a=vadr[i].d; b=vadr[i].a; break; } // build edge matrix pa = padr[a]*ml; pb = padr[b]*ml; m.off=(pa+pb)*0.5; RectangularSystem(!(pb-pa),&m.v1,&m.v2); m.v3=pb-pa; for (j=0; j<cpcnt; j++) rpadr[poff+j] = cpadr[j]*m; for (j=0; j<cvcnt; j++) { rvadr[voff+j] = CPolygon(cvadr[j].a+poff,cvadr[j].b+poff,cvadr[j].c+poff,cvadr[j].d+poff); ruvw->Copy(duvwptr,voff+j,suvwptr,j); } poff+=cpcnt; voff+=cvcnt; } } // update object as point geometry has changed pp->Message(MSG_UPDATE); ok=TRUE; Error: blDelete(sphere); blDelete(cyl); if (!ok) blDelete(pp); return pp; }