Пример #1
0
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;
}
Пример #2
0
// go through every (child) object
static Bool Recurse(HierarchyHelp *hh, BaseThread *bt, BaseObject *main, BaseObject *op, const Matrix &ml, Real srad, Real crad, LONG sub, Bool single)
{
	// test if input object if polygonal
	if (op->GetType()==Opolygon)
	{
		BaseObject *tp   = NULL;
		PolyInfo	 *pli  = NULL;
		const Vector *padr = ToPoly(op)->GetPointR();
		Vector pa,pb;
		LONG       pcnt  = ToPoly(op)->GetPointCount(),i,side,a=0,b=0;
		const CPolygon *vadr = ToPoly(op)->GetPolygonR();
		LONG       vcnt  = ToPoly(op)->GetPolygonCount();
		Matrix     m;
		Neighbor	 n;

		// load names from resource
		String		 pstr = GeLoadString(IDS_ATOM_POINT);
		String		 estr = GeLoadString(IDS_ATOM_EDGE);

		// initialize neighbor class
		if (!n.Init(pcnt,vadr,vcnt,NULL)) return FALSE;

		// create separate objects
		// if this option is enabled no polygonal geometry is build - more parametric objects
		// are returned instead
		if (single)
		{
			for (i=0; i<pcnt; i++)
			{
				// alloc sphere primitive
				tp=BaseObject::Alloc(Osphere);
				if (!tp) return FALSE;

				// add phong tag
				if (!tp->MakeTag(Tphong)) return FALSE;
				tp->SetName(pstr+" "+LongToString(i));

				// set object parameters
				BaseContainer *bc = tp->GetDataInstance();
				bc->SetReal(PRIM_SPHERE_RAD,srad);
				bc->SetReal(PRIM_SPHERE_SUB,sub);

				// insert as last object under main
				tp->InsertUnderLast(main);

				// set position in local coordinates
				tp->SetRelPos(padr[i]*ml);
			}

			for (i=0; i<vcnt; i++)
			{
				// get polygon info for i-th polygon
				pli = n.GetPolyInfo(i);

				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;

					// alloc cylinder primitive
					tp=BaseObject::Alloc(Ocylinder);
					if (!tp) return FALSE;

					// add phong tag
					if (!tp->MakeTag(Tphong)) return FALSE;

					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;
					}

					tp->SetName(estr+" "+LongToString(pli->edge[side]));

					pa = padr[a]*ml;
					pb = padr[b]*ml;

					// set object parameters
					BaseContainer *bc = tp->GetDataInstance();
					bc->SetReal(PRIM_CYLINDER_RADIUS,crad);
					bc->SetReal(PRIM_CYLINDER_HEIGHT,Len(pb-pa));
					bc->SetReal(PRIM_AXIS,4);
					bc->SetLong(PRIM_CYLINDER_CAPS,FALSE);
					bc->SetLong(PRIM_CYLINDER_HSUB,1);
					bc->SetLong(PRIM_CYLINDER_SEG,sub);

					// place cylinder at edge center
					tp->SetRelPos((pa+pb)*0.5);

					// build edge matrix
					m.v3=!(pb-pa);
					RectangularSystem(m.v3,&m.v1,&m.v2);
					tp->SetRelRot(MatrixToHPB(m, tp->GetRotationOrder()));

					// insert as last object under main
					tp->InsertUnderLast(main);
				}
			}
		}
		else
		{
			// check if polygonal geometry has to be built
			tp = BuildPolyHull(ToPoly(op),ml,srad,crad,sub,hh->GetLOD(),&n,bt);

			if (tp)
			{
				tp->SetName(op->GetName());
				tp->InsertUnderLast(main);

				// check if isoparm geometry has to be built
				if (hh->GetBuildFlags()&BUILDFLAGS_ISOPARM)
				{
					LineObject *ip = BuildIsoHull(ToPoly(op),ml,srad,crad,sub,hh->GetLOD(),&n,bt);

					// isoparm always needs to be set into a polygon object
					if (ip) tp->SetIsoparm(ip);
				}
			}
		}
	}

	for (op=op->GetDown(); op; op=op->GetNext())
		if (!Recurse(hh,bt,main,op,ml*op->GetMl(),srad,crad,sub,single)) return FALSE;

	// check for user break
	return !bt || !bt->TestBreak();
}