void MatMod::ModifyObject(TimeValue t, ModContext &mc, ObjectState *os, INode *node) { Interval valid = FOREVER; int id; pblock->GetValue(PB_MATID,t,id,valid); id--; if (id<0) id = 0; if (id>0xffff) id = 0xffff; // For version 4 and later, we process patch meshes as they are and pass them on. Earlier // versions converted to TriMeshes (done below). For adding other new types of objects, add // them here! #ifndef NO_PATCHES if(version >= MATMOD_VER4 && os->obj->IsSubClassOf(patchObjectClassID)) { PatchObject *patchOb = (PatchObject *)os->obj; PatchMesh &pmesh = patchOb->GetPatchMesh(t); BOOL useSel = pmesh.selLevel >= PO_PATCH; for (int i=0; i<pmesh.getNumPatches(); i++) { if (!useSel || pmesh.patchSel[i]) { pmesh.setPatchMtlIndex(i,(MtlID)id); } } pmesh.InvalidateGeomCache(); // Do this because there isn't a topo cache in PatchMesh patchOb->UpdateValidity(TOPO_CHAN_NUM,valid); } else #endif // NO_PATCHES // Process PolyObjects if(os->obj->IsSubClassOf(polyObjectClassID)) { PolyObject *polyOb = (PolyObject *)os->obj; MNMesh &mesh = polyOb->GetMesh(); BOOL useSel = mesh.selLevel == MNM_SL_FACE; for (int i=0; i<mesh.numf; i++) { if (!useSel || mesh.f[i].GetFlag(MN_SEL)) { mesh.f[i].material = (MtlID)id; } } polyOb->UpdateValidity(TOPO_CHAN_NUM,valid); } else // If it's a TriObject, process it if(os->obj->IsSubClassOf(triObjectClassID)) { TriObject *triOb = (TriObject *)os->obj; DoMaterialSet(triOb, id); triOb->UpdateValidity(TOPO_CHAN_NUM,valid); } else // Fallback position: If it can convert to a TriObject, do it! if(os->obj->CanConvertToType(triObjectClassID)) { TriObject *triOb = (TriObject *)os->obj->ConvertToType(t, triObjectClassID); // Now stuff this into the pipeline! os->obj = triOb; DoMaterialSet(triOb, id); triOb->UpdateValidity(TOPO_CHAN_NUM,valid); } else return; // Do nothing if it can't convert to triObject }
PatchObject* PatchObject::clone(PatchObject* par_obj, Address base, CFGMaker* cm, PatchCallback *cb) { patchapi_debug("Clone PatchObject at %lx", base); PatchObject* obj = new PatchObject(par_obj, base, cm, cb); obj->copyCFG(par_obj); return obj; }
void SubscriberManager::build_patch(PatchObject& po, const Bindings& update_bindings, const AssociatedURIs& associated_uris) { po.set_update_bindings(SubscriberDataUtils::copy_bindings(update_bindings)); po.set_associated_uris(associated_uris); }
virtual bool check(SpPoint* pt) { PatchFunction* f = sp::Callee(pt); if (!f) return false; sp_print("StackArrayChecker"); // getAllVariables PatchObject* obj = pt->obj(); using namespace Dyninst::ParseAPI; using namespace Dyninst::SymtabAPI; SymtabCodeSource* cs = static_cast<SymtabCodeSource*>(obj->co()->cs()); Symtab* sym = cs->getSymtabObject(); std::vector<Symbol*> symbols; std::vector<SymtabAPI::Function*> funcs; sym->getAllFunctions(funcs); for (unsigned i = 0; i < funcs.size(); i ++) { if (funcs[i]->getOffset() == f->addr()) { std::vector<localVar*> vars; funcs[i]->getLocalVariables(vars); for (unsigned j = 0; j < vars.size(); j ++) { typeArray* t = vars[j]->getType()->getArrayType(); if (!t) continue; sp_print("%s: [%lx, %lx]", vars[j]->getName().c_str(), t->getLow(), t->getHigh()); } } } return true; }
void SubscriberManager::build_patch(PatchObject& po, const std::vector<std::string>& remove_bindings, const std::vector<std::string>& remove_subscriptions) { po.set_remove_bindings(remove_bindings); po.set_remove_subscriptions(remove_subscriptions); po.set_increment_cseq(true); }
void SubscriberManager::build_patch(PatchObject& po, const Subscriptions& update_subscriptions, const std::vector<std::string>& remove_subscriptions, const AssociatedURIs& associated_uris) { po.set_update_subscriptions(SubscriberDataUtils::copy_subscriptions(update_subscriptions)); po.set_remove_subscriptions(remove_subscriptions); po.set_associated_uris(associated_uris); po.set_increment_cseq(true); }
const PatchBlock::edgelist& PatchBlock::sources() { if (srclist_.empty()) { for (ParseAPI::Block::edgelist::const_iterator iter = block_->sources().begin(); iter != block_->sources().end(); ++iter) { // search for edge in object of source block PatchObject *obj = obj_->addrSpace()->findObject((*iter)->src()->obj()); PatchEdge *newEdge = obj->getEdge(*iter, NULL, this); srclist_.push_back(newEdge); } } return srclist_; }
Object* TriObject::ConvertToType(TimeValue t, Class_ID cid) { if (cid==defObjectClassID) return this; if (cid==mapObjectClassID) return this; if (cid==triObjectClassID) return this; #ifndef NO_PATCHES if (cid==patchObjectClassID) { PatchObject *patchob = new PatchObject(); patchob->patch = mesh; patchob->SetChannelValidity(TOPO_CHAN_NUM,ChannelValidity (t, TOPO_CHAN_NUM)); patchob->SetChannelValidity(GEOM_CHAN_NUM,ChannelValidity (t, GEOM_CHAN_NUM)); patchob->SetChannelValidity(TEXMAP_CHAN_NUM,ChannelValidity (t, TEXMAP_CHAN_NUM)); patchob->SetChannelValidity(VERT_COLOR_CHAN_NUM,ChannelValidity (t, VERT_COLOR_CHAN_NUM)); return patchob; } #endif #ifdef DESIGN_VER if (cid == GENERIC_AMSOLID_CLASS_ID) { Object* solid = (Object*)CreateInstance(GEOMOBJECT_CLASS_ID, GENERIC_AMSOLID_CLASS_ID); assert(solid); if(solid) { IGeomImp* cacheptr = (IGeomImp*)(solid->GetInterface(I_GEOMIMP)); assert(cacheptr); if(cacheptr) { // bool res = cacheptr->createConvexHull(mesh.verts, mesh.getNumVerts()); cacheptr->Init((void*)&mesh, MAX_MESH_ID); bool res = !cacheptr->isNull(); solid->ReleaseInterface(I_GEOMIMP, cacheptr); solid->SetChannelValidity(TOPO_CHAN_NUM,ChannelValidity (t, TOPO_CHAN_NUM)); solid->SetChannelValidity(GEOM_CHAN_NUM,ChannelValidity (t, GEOM_CHAN_NUM)); solid->SetChannelValidity(TEXMAP_CHAN_NUM,ChannelValidity (t, TEXMAP_CHAN_NUM)); solid->SetChannelValidity(VERT_COLOR_CHAN_NUM,ChannelValidity (t, VERT_COLOR_CHAN_NUM)); if(res) { return solid; } } } } #endif return Object::ConvertToType (t, cid); }
Object* SimpleObject::ConvertToType(TimeValue t, Class_ID obtype) { if (obtype==defObjectClassID||obtype==triObjectClassID||obtype==mapObjectClassID) { TriObject *triob; UpdateMesh(t); triob = CreateNewTriObject(); triob->GetMesh() = mesh; triob->SetChannelValidity(TOPO_CHAN_NUM,ObjectValidity(t)); triob->SetChannelValidity(GEOM_CHAN_NUM,ObjectValidity(t)); return triob; } else if (obtype == patchObjectClassID) { UpdateMesh(t); PatchObject *patchob = new PatchObject(); patchob->patch = mesh; // Handy Mesh->PatchMesh conversion patchob->SetChannelValidity(TOPO_CHAN_NUM,ObjectValidity(t)); patchob->SetChannelValidity(GEOM_CHAN_NUM,ObjectValidity(t)); return patchob; } return Object::ConvertToType(t,obtype); }
Object* TriPatchObject::ConvertToType(TimeValue t, Class_ID obtype) { if(obtype == patchObjectClassID || obtype == defObjectClassID || obtype == mapObjectClassID) { PatchObject *ob; UpdatePatchMesh(t); ob = new PatchObject(); ob->patch = patch; ob->SetChannelValidity(TOPO_CHAN_NUM,ObjectValidity(t)); ob->SetChannelValidity(GEOM_CHAN_NUM,ObjectValidity(t)); return ob; } if(obtype == triObjectClassID) { TriObject *ob = CreateNewTriObject(); PrepareMesh(t); ob->GetMesh() = patch.GetMesh(); ob->SetChannelValidity(TOPO_CHAN_NUM,ObjectValidity(t)); ob->SetChannelValidity(GEOM_CHAN_NUM,ObjectValidity(t)); return ob; } #ifndef NO_NURBS if (obtype==EDITABLE_SURF_CLASS_ID) { PatchObject *pob; UpdatePatchMesh(t); pob = new PatchObject(); pob->patch = patch; Object *ob = BuildEMObjectFromPatchObject(pob); delete pob; ob->SetChannelValidity(TOPO_CHAN_NUM, ObjectValidity(t)); ob->SetChannelValidity(GEOM_CHAN_NUM, ObjectValidity(t)); return ob; } #endif if (Object::CanConvertToType (obtype)) return Object::ConvertToType (t, obtype); if (CanConvertPatchObject (obtype)) { PatchObject *ob; UpdatePatchMesh(t); ob = new PatchObject(); ob->patch = patch; ob->SetChannelValidity(TOPO_CHAN_NUM,ObjectValidity(t)); ob->SetChannelValidity(GEOM_CHAN_NUM,ObjectValidity(t)); Object *ret = ob->ConvertToType (t, obtype); ob->DeleteThis (); return ret; } return NULL; }
Object* SimpleObject::ConvertToType(TimeValue t, Class_ID obtype) { if (obtype==defObjectClassID||obtype==triObjectClassID||obtype==mapObjectClassID) { TriObject *triob; UpdateMesh(t); triob = CreateNewTriObject(); triob->GetMesh() = mesh; triob->SetChannelValidity(TOPO_CHAN_NUM,ObjectValidity(t)); triob->SetChannelValidity(GEOM_CHAN_NUM,ObjectValidity(t)); return triob; } #ifndef NO_PATCHES if (obtype == patchObjectClassID) { UpdateMesh(t); PatchObject *patchob = new PatchObject(); patchob->patch = mesh; // Handy Mesh->PatchMesh conversion patchob->SetChannelValidity(TOPO_CHAN_NUM,ObjectValidity(t)); patchob->SetChannelValidity(GEOM_CHAN_NUM,ObjectValidity(t)); return patchob; } #endif if (Object::CanConvertToType (obtype)) { UpdateMesh (t); return Object::ConvertToType(t,obtype); } if (CanConvertTriObject(obtype)) { UpdateMesh (t); TriObject *triob = CreateNewTriObject (); triob->GetMesh() = mesh; triob->SetChannelValidity(TOPO_CHAN_NUM,ObjectValidity(t)); triob->SetChannelValidity(GEOM_CHAN_NUM,ObjectValidity(t)); Object *ob = triob->ConvertToType (t, obtype); if (ob != triob) triob->DeleteThis (); // (ob should never = tob.) return ob; } return NULL; }
Object* TorusObject::ConvertToType(TimeValue t, Class_ID obtype) { #ifndef NO_PATCHES if (obtype == patchObjectClassID) { Interval valid = FOREVER; float radius1, radius2; int genUVs; pblock->GetValue(PB_RADIUS,t,radius1,valid); pblock->GetValue(PB_RADIUS2,t,radius2,valid); pblock->GetValue(PB_GENUVS,t,genUVs,valid); PatchObject *ob = new PatchObject(); BuildTorusPatch(t,ob->patch,radius1,radius2,genUVs, GetUsePhysicalScaleUVs()); ob->SetChannelValidity(TOPO_CHAN_NUM,valid); ob->SetChannelValidity(GEOM_CHAN_NUM,valid); ob->UnlockObject(); return ob; } #endif #ifndef NO_NURBS if (obtype == EDITABLE_SURF_CLASS_ID) { Interval valid = FOREVER; float radius, radius2, pie1, pie2; int sliceon, genUVs; pblock->GetValue(PB_RADIUS,t,radius,valid); pblock->GetValue(PB_RADIUS2,t,radius2,valid); pblock->GetValue(PB_PIESLICE1,t,pie1,valid); pblock->GetValue(PB_PIESLICE2,t,pie2,valid); pblock->GetValue(PB_SLICEON,t,sliceon,valid); pblock->GetValue(PB_GENUVS,t,genUVs,valid); Object *ob = BuildNURBSTorus(radius, radius2, sliceon, pie1, pie2, genUVs); ob->SetChannelValidity(TOPO_CHAN_NUM,valid); ob->SetChannelValidity(GEOM_CHAN_NUM,valid); ob->UnlockObject(); return ob; } #endif #ifdef DESIGN_VER if (obtype == GENERIC_AMSOLID_CLASS_ID) { Interval valid = FOREVER; float radius1, radius2, pie1, pie2; int sliceon, genUVs, sides, segs; pblock->GetValue(PB_RADIUS,t,radius1,valid); pblock->GetValue(PB_RADIUS2,t,radius2,valid); pblock->GetValue(PB_PIESLICE1,t,pie1,valid); pblock->GetValue(PB_PIESLICE2,t,pie2,valid); pblock->GetValue(PB_SLICEON,t,sliceon,valid); pblock->GetValue(PB_GENUVS,t,genUVs,valid); pblock->GetValue(PB_SIDES,t,sides,valid); pblock->GetValue(PB_SEGMENTS,t,segs,valid); int smooth; pblock->GetValue(PB_SMOOTH,t,smooth,valid); if (radius1 < 0.0f) radius1 = 0.0f; if (radius2 < 0.0f) radius2 = 0.0f; Object* solid = (Object*)CreateInstance(GEOMOBJECT_CLASS_ID, GENERIC_AMSOLID_CLASS_ID); assert(solid); if(solid) { IGeomImp* cacheptr = (IGeomImp*)(solid->GetInterface(I_GEOMIMP)); assert(cacheptr); if(cacheptr) { bool res = cacheptr->createTorus(radius1, radius2, sides, segs, smooth); solid->ReleaseInterface(I_GEOMIMP, cacheptr); if(res) return solid; else { solid->DeleteMe(); } } } return NULL; } #endif return SimpleObject::ConvertToType(t,obtype); }
void RelaxMod::ModifyObject(TimeValue t, ModContext &mc, ObjectState * os, INode *node) { // Get our personal validity interval... Interval valid = GetValidity(t); // and intersect it with the channels we use as input (see ChannelsUsed) valid &= os->obj->ChannelValidity (t, GEOM_CHAN_NUM); valid &= os->obj->ChannelValidity (t, TOPO_CHAN_NUM); valid &= os->obj->ChannelValidity (t, SUBSEL_TYPE_CHAN_NUM); valid &= os->obj->ChannelValidity (t, SELECT_CHAN_NUM); Matrix3 modmat,minv; if (mc.localData == NULL) mc.localData = new RelaxModData; RelaxModData *rd = (RelaxModData *) mc.localData; TriObject *triObj = NULL; PatchObject *patchObj = NULL; PolyObject *polyObj = NULL; BOOL converted = FALSE; // For version 4 and later, we process patch or poly meshes as they are and pass them on. // Earlier versions converted to TriMeshes (done below). // For adding other new types of objects, add them here! #ifndef NO_PATCHES if(version >= RELAXMOD_VER4 && os->obj->IsSubClassOf(patchObjectClassID)) { patchObj = (PatchObject *)os->obj; } else // If it's a TriObject, process it #endif // NO_PATCHES if(os->obj->IsSubClassOf(triObjectClassID)) { triObj = (TriObject *)os->obj; } else if (os->obj->IsSubClassOf (polyObjectClassID)) { polyObj = (PolyObject *) os->obj; } else // If it can convert to a TriObject, do it if(os->obj->CanConvertToType(triObjectClassID)) { triObj = (TriObject *)os->obj->ConvertToType(t, triObjectClassID); converted = TRUE; } else return; // We can't deal with it! Mesh *mesh = triObj ? &(triObj->GetMesh()) : NULL; #ifndef NO_PATCHES PatchMesh &pmesh = patchObj ? patchObj->GetPatchMesh(t) : *((PatchMesh *)NULL); #else PatchMesh &pmesh = *((PatchMesh *)NULL); #endif // NO_PATCHES float relax, wtdRelax; // mjm - 4.8.99 int iter; BOOL boundary, saddle; pblock->GetValue (PB_RELAX, t, relax, FOREVER); pblock->GetValue (PB_ITER, t, iter, FOREVER); pblock->GetValue (PB_BOUNDARY, t, boundary, FOREVER); pblock->GetValue (PB_SADDLE, t, saddle, FOREVER); LimitValue (relax, MIN_RELAX, MAX_RELAX); LimitValue (iter, MIN_ITER, MAX_ITER); if(triObj) { int i, j, max; DWORD selLevel = mesh->selLevel; // mjm - 4.8.99 - add support for soft selection // sca - 4.29.99 - extended soft selection support to cover EDGE and FACE selection levels. float *vsw = (selLevel!=MESH_OBJECT) ? mesh->getVSelectionWeights() : NULL; if (rd->ivalid.InInterval(t) && (mesh->numVerts != rd->vnum)) { // Shouldn't happen, but does with Loft bug and may with other bugs. rd->ivalid.SetEmpty (); } if (!rd->ivalid.InInterval(t)) { rd->SetVNum (mesh->numVerts); for (i=0; i<rd->vnum; i++) { rd->fnum[i]=0; rd->nbor[i].ZeroCount(); } rd->sel.ClearAll (); DWORD *v; int k1, k2, origmax; for (i=0; i<mesh->numFaces; i++) { v = mesh->faces[i].v; for (j=0; j<3; j++) { if ((selLevel==MESH_FACE) && mesh->faceSel[i]) rd->sel.Set(v[j]); if ((selLevel==MESH_EDGE) && mesh->edgeSel[i*3+j]) rd->sel.Set(v[j]); if ((selLevel==MESH_EDGE) && mesh->edgeSel[i*3+(j+2)%3]) rd->sel.Set(v[j]); origmax = max = rd->nbor[v[j]].Count(); rd->fnum[v[j]]++; for (k1=0; k1<max; k1++) if (rd->nbor[v[j]][k1] == v[(j+1)%3]) break; if (k1==max) { rd->nbor[v[j]].Append (1, v+(j+1)%3, 1); max++; } for (k2=0; k2<max; k2++) if (rd->nbor[v[j]][k2] == v[(j+2)%3]) break; if (k2==max) { rd->nbor[v[j]].Append (1, v+(j+2)%3, 1); max++; } if (max>origmax) rd->vis[v[j]].SetSize (max, TRUE); if (mesh->faces[i].getEdgeVis (j)) rd->vis[v[j]].Set (k1); else if (k1>=origmax) rd->vis[v[j]].Clear (k1); if (mesh->faces[i].getEdgeVis ((j+2)%3)) rd->vis[v[j]].Set (k2); else if (k2>= origmax) rd->vis[v[j]].Clear (k2); } } // mjm - begin - 4.8.99 // if (selLevel==MESH_VERTEX) rd->sel = mesh->vertSel; if (selLevel==MESH_VERTEX) rd->sel = mesh->vertSel; else if (selLevel==MESH_OBJECT) rd->sel.SetAll (); // mjm - end rd->ivalid = os->obj->ChannelValidity (t, TOPO_CHAN_NUM); rd->ivalid &= os->obj->ChannelValidity (t, SUBSEL_TYPE_CHAN_NUM); rd->ivalid &= os->obj->ChannelValidity (t, SELECT_CHAN_NUM); } Tab<float> vangles; if (saddle) vangles.SetCount (rd->vnum); Point3 *hold = new Point3[rd->vnum]; int act; for (int k=0; k<iter; k++) { for (i=0; i<rd->vnum; i++) hold[i] = triObj->GetPoint(i); if (saddle) mesh->FindVertexAngles (vangles.Addr(0)); for (i=0; i<rd->vnum; i++) { // mjm - begin - 4.8.99 // if ((selLevel!=MESH_OBJECT) && (!rd->sel[i])) continue; if ( (!rd->sel[i] ) && (!vsw || vsw[i] == 0) ) continue; // mjm - end if (saddle && (vangles[i] <= 2*PI*.99999f)) continue; max = rd->nbor[i].Count(); if (boundary && (rd->fnum[i] < max)) continue; if (max<1) continue; Point3 avg(0.0f, 0.0f, 0.0f); for (j=0,act=0; j<max; j++) { if (!rd->vis[i][j]) continue; act++; avg += hold[rd->nbor[i][j]]; } if (act<1) continue; // mjm - begin - 4.8.99 wtdRelax = (!rd->sel[i]) ? relax * vsw[i] : relax; triObj->SetPoint (i, hold[i]*(1-wtdRelax) + avg*wtdRelax/((float)act)); // triObj->SetPoint (i, hold[i]*(1-relax) + avg*relax/((float)act)); // mjm - end } } delete [] hold; } if (polyObj) { int i, j, max; MNMesh & mm = polyObj->mm; float *vsw = (mm.selLevel!=MNM_SL_OBJECT) ? mm.getVSelectionWeights() : NULL; if (rd->ivalid.InInterval(t) && (mm.numv != rd->vnum)) { // Shouldn't happen, but does with Loft bug and may with other bugs. rd->ivalid.SetEmpty (); } if (!rd->ivalid.InInterval(t)) { rd->SetVNum (mm.numv); for (i=0; i<rd->vnum; i++) { rd->fnum[i]=0; rd->nbor[i].ZeroCount(); } rd->sel = mm.VertexTempSel (); int k1, k2, origmax; for (i=0; i<mm.numf; i++) { int deg = mm.f[i].deg; int *vtx = mm.f[i].vtx; for (j=0; j<deg; j++) { Tab<DWORD> & nbor = rd->nbor[vtx[j]]; origmax = max = nbor.Count(); rd->fnum[vtx[j]]++; DWORD va = vtx[(j+1)%deg]; DWORD vb = vtx[(j+deg-1)%deg]; for (k1=0; k1<max; k1++) if (nbor[k1] == va) break; if (k1==max) { nbor.Append (1, &va, 1); max++; } for (k2=0; k2<max; k2++) if (nbor[k2] == vb) break; if (k2==max) { nbor.Append (1, &vb, 1); max++; } } } rd->ivalid = os->obj->ChannelValidity (t, TOPO_CHAN_NUM); rd->ivalid &= os->obj->ChannelValidity (t, SUBSEL_TYPE_CHAN_NUM); rd->ivalid &= os->obj->ChannelValidity (t, SELECT_CHAN_NUM); } Tab<float> vangles; if (saddle) vangles.SetCount (rd->vnum); Tab<Point3> hold; hold.SetCount (rd->vnum); int act; for (int k=0; k<iter; k++) { for (i=0; i<rd->vnum; i++) hold[i] = mm.P(i); if (saddle) FindVertexAngles (mm, vangles.Addr(0)); for (i=0; i<rd->vnum; i++) { if ((!rd->sel[i]) && (!vsw || vsw[i] == 0) ) continue; if (saddle && (vangles[i] <= 2*PI*.99999f)) continue; max = rd->nbor[i].Count(); if (boundary && (rd->fnum[i] < max)) continue; if (max<1) continue; Point3 avg(0.0f, 0.0f, 0.0f); for (j=0,act=0; j<max; j++) { act++; avg += hold[rd->nbor[i][j]]; } if (act<1) continue; wtdRelax = (!rd->sel[i]) ? relax * vsw[i] : relax; polyObj->SetPoint (i, hold[i]*(1-wtdRelax) + avg*wtdRelax/((float)act)); } } } #ifndef NO_PATCHES else if(patchObj) { int i, j, max; DWORD selLevel = pmesh.selLevel; // mjm - 4.8.99 - add support for soft selection // sca - 4.29.99 - extended soft selection support to cover EDGE and FACE selection levels. float *vsw = (selLevel!=PATCH_OBJECT) ? pmesh.GetVSelectionWeights() : NULL; if (rd->ivalid.InInterval(t) && (pmesh.numVerts != rd->vnum)) { // Shouldn't happen, but does with Loft bug and may with other bugs. rd->ivalid.SetEmpty (); } if (!rd->ivalid.InInterval(t)) { int vecBase = pmesh.numVerts; rd->SetVNum (pmesh.numVerts + pmesh.numVecs); for (i=0; i<rd->vnum; i++) { rd->fnum[i]=1; // For patches, this means it's not a boundary rd->nbor[i].ZeroCount(); } rd->sel.ClearAll (); for (i=0; i<pmesh.numPatches; i++) { Patch &p = pmesh.patches[i]; int vecLimit = p.type * 2; for (j=0; j<p.type; j++) { PatchEdge &e = pmesh.edges[p.edge[j]]; BOOL isBoundary = (e.patches.Count() < 2) ? TRUE : FALSE; int theVert = p.v[j]; int nextVert = p.v[(j+1)%p.type]; int nextVec = p.vec[j*2] + vecBase; int nextVec2 = p.vec[j*2+1] + vecBase; int prevEdge = (j+p.type-1)%p.type; int prevVec = p.vec[prevEdge*2+1] + vecBase; int prevVec2 = p.vec[prevEdge*2] + vecBase; int theInterior = p.interior[j] + vecBase; // Establish selection bits if ((selLevel==PATCH_PATCH) && pmesh.patchSel[i]) { rd->sel.Set(theVert); rd->sel.Set(nextVec); rd->sel.Set(prevVec); rd->sel.Set(theInterior); } else if ((selLevel==PATCH_EDGE) && pmesh.edgeSel[p.edge[j]]) { rd->sel.Set(e.v1); rd->sel.Set(e.vec12 + vecBase); rd->sel.Set(e.vec21 + vecBase); rd->sel.Set(e.v2); } else if ((selLevel==PATCH_VERTEX) && pmesh.vertSel[theVert]) { rd->sel.Set(theVert); rd->sel.Set(nextVec); rd->sel.Set(prevVec); rd->sel.Set(theInterior); } // Set boundary flags if necessary if(isBoundary) { rd->fnum[theVert] = 0; rd->fnum[nextVec] = 0; rd->fnum[nextVec2] = 0; rd->fnum[nextVert] = 0; } // First process the verts int work = theVert; max = rd->nbor[work].Count(); // Append the neighboring vectors rd->MaybeAppendNeighbor(work, nextVec, max); rd->MaybeAppendNeighbor(work, prevVec, max); rd->MaybeAppendNeighbor(work, theInterior, max); // Now process the edge vectors work = nextVec; max = rd->nbor[work].Count(); // Append the neighboring points rd->MaybeAppendNeighbor(work, theVert, max); rd->MaybeAppendNeighbor(work, theInterior, max); rd->MaybeAppendNeighbor(work, prevVec, max); rd->MaybeAppendNeighbor(work, nextVec2, max); rd->MaybeAppendNeighbor(work, p.interior[(j+1)%p.type] + vecBase, max); work = prevVec; max = rd->nbor[work].Count(); // Append the neighboring points rd->MaybeAppendNeighbor(work, theVert, max); rd->MaybeAppendNeighbor(work, theInterior, max); rd->MaybeAppendNeighbor(work, nextVec, max); rd->MaybeAppendNeighbor(work, prevVec2, max); rd->MaybeAppendNeighbor(work, p.interior[(j+p.type-1)%p.type] + vecBase, max); // Now append the interior, if not auto if(!p.IsAuto()) { work = theInterior; max = rd->nbor[work].Count(); // Append the neighboring points rd->MaybeAppendNeighbor(work, p.v[j], max); rd->MaybeAppendNeighbor(work, nextVec, max); rd->MaybeAppendNeighbor(work, nextVec2, max); rd->MaybeAppendNeighbor(work, prevVec, max); rd->MaybeAppendNeighbor(work, prevVec2, max); for(int k = 1; k < p.type; ++k) rd->MaybeAppendNeighbor(work, p.interior[(j+k)%p.type] + vecBase, max); } } } // mjm - begin - 4.8.99 if (selLevel==PATCH_VERTEX) { for (int i=0; i<pmesh.numVerts; ++i) { if (pmesh.vertSel[i]) rd->sel.Set(i); } } else if (selLevel==PATCH_OBJECT) rd->sel.SetAll(); // mjm - end rd->ivalid = os->obj->ChannelValidity (t, TOPO_CHAN_NUM); rd->ivalid &= os->obj->ChannelValidity (t, SUBSEL_TYPE_CHAN_NUM); rd->ivalid &= os->obj->ChannelValidity (t, SELECT_CHAN_NUM); } Tab<float> vangles; if (saddle) vangles.SetCount (rd->vnum); Point3 *hold = new Point3[rd->vnum]; int act; for (int k=0; k<iter; k++) { for (i=0; i<rd->vnum; i++) hold[i] = patchObj->GetPoint(i); if (saddle) FindVertexAngles(pmesh, vangles.Addr(0)); for (i=0; i<rd->vnum; i++) { // mjm - begin - 4.8.99 // if ((selLevel!=MESH_OBJECT) && (!rd->sel[i])) continue; if ( (!rd->sel[i] ) && (!vsw || vsw[i] == 0) ) continue; // mjm - end if (saddle && (i < pmesh.numVerts) && (vangles[i] <= 2*PI*.99999f)) continue; max = rd->nbor[i].Count(); if (boundary && !rd->fnum[i]) continue; if (max<1) continue; Point3 avg(0.0f, 0.0f, 0.0f); for (j=0,act=0; j<max; j++) { act++; avg += hold[rd->nbor[i][j]]; } if (act<1) continue; // mjm - begin - 4.8.99 wtdRelax = (!rd->sel[i]) ? relax * vsw[i] : relax; patchObj->SetPoint (i, hold[i]*(1-wtdRelax) + avg*wtdRelax/((float)act)); // patchObj->SetPoint (i, hold[i]*(1-relax) + avg*relax/((float)act)); // mjm - end } } delete [] hold; patchObj->patch.computeInteriors(); patchObj->patch.ApplyConstraints(); } #endif // NO_PATCHES if(!converted) { os->obj->SetChannelValidity(GEOM_CHAN_NUM, valid); } else { // Stuff converted object into the pipeline! triObj->SetChannelValidity(TOPO_CHAN_NUM, valid); triObj->SetChannelValidity(GEOM_CHAN_NUM, valid); triObj->SetChannelValidity(TEXMAP_CHAN_NUM, valid); triObj->SetChannelValidity(MTL_CHAN_NUM, valid); triObj->SetChannelValidity(SELECT_CHAN_NUM, valid); triObj->SetChannelValidity(SUBSEL_TYPE_CHAN_NUM, valid); triObj->SetChannelValidity(DISP_ATTRIB_CHAN_NUM, valid); os->obj = triObj; } }
void MirrorMod::ModifyObject( TimeValue t, ModContext &mc, ObjectState *os, INode *node) { Matrix3 itm = CompMatrix(t,NULL,&mc); Matrix3 tm = Inverse(itm); Interval iv = FOREVER; int axis, copy; float offset; pblock->GetValue(PB_AXIS,t,axis,iv); pblock->GetValue(PB_COPY,t,copy,iv); pblock->GetValue(PB_OFFSET,t,offset,iv); DWORD oldLevel; BOOL convertedShape = FALSE; BitArray oldFaceSelections; // support for TriObjects if (os->obj->IsSubClassOf(triObjectClassID)) { TriObject *tobj = (TriObject*)os->obj; Mesh &mesh = tobj->GetMesh(); switch (mesh.selLevel) { case MESH_OBJECT: mesh.faceSel.SetAll(); break; case MESH_VERTEX: { for (int i=0; i<mesh.getNumFaces(); i++) { for (int j=0; j<3; j++) { if (mesh.vertSel[mesh.faces[i].v[j]]) { mesh.faceSel.Set(i); } } } break; } case MESH_EDGE: { for (int i=0; i<mesh.getNumFaces(); i++) { for (int j=0; j<3; j++) { if (mesh.edgeSel[i*3+j]) { mesh.faceSel.Set(i); } } } break; } } oldLevel = mesh.selLevel; mesh.selLevel = MESH_FACE; if (copy) { mesh.CloneFaces(mesh.faceSel); mesh.ClearVSelectionWeights (); } if (axis<3) { for (int i=0; i<mesh.getNumFaces(); i++) { if (mesh.faceSel[i]) mesh.FlipNormal(i); } } } #ifndef NO_PATCHES // support for PatchObjects if (os->obj->IsSubClassOf(patchObjectClassID)) { PatchObject *pobj = (PatchObject*)os->obj; PatchMesh &pmesh = pobj->GetPatchMesh(t); switch (pmesh.selLevel) { case PATCH_OBJECT: pmesh.patchSel.SetAll(); break; case PATCH_VERTEX: { for (int i=0; i<pmesh.getNumPatches(); i++) { Patch &p = pmesh.patches[i]; for (int j=0; j<p.type; j++) { if (pmesh.vertSel[p.v[j]]) { pmesh.patchSel.Set(i); break; } } } break; } case PATCH_EDGE: { for (int i=0; i<pmesh.getNumPatches(); i++) { Patch &p = pmesh.patches[i]; for (int j=0; j<p.type; j++) { if (pmesh.edgeSel[p.edge[j]]) { pmesh.patchSel.Set(i); break; } } } break; } } oldLevel = pmesh.selLevel; pmesh.selLevel = PATCH_PATCH; if (copy) pmesh.ClonePatchParts(); // Copy the selected patches if (axis<3) pmesh.FlipPatchNormal(-1); // Flip selected normals } #endif // NO_PATCHES // support for PolyObjects else if (os->obj->IsSubClassOf(polyObjectClassID)) { PolyObject * pPolyOb = (PolyObject*)os->obj; MNMesh &mesh = pPolyOb->GetMesh(); // Luna task 747 // We don't support specified normals here because it would take special code mesh.ClearSpecifiedNormals (); BitArray faceSelections; mesh.getFaceSel (faceSelections); switch (mesh.selLevel) { case MNM_SL_OBJECT: faceSelections.SetAll(); break; case MNM_SL_VERTEX: { faceSelections.ClearAll (); for (int i=0; i<mesh.FNum(); i++) { for (int j=0; j<mesh.F(i)->deg; j++) { int vertIndex = mesh.F(i)->vtx[j]; if (mesh.V(vertIndex)->GetFlag(MN_SEL)) { faceSelections.Set(i); break; } } } break; } case MNM_SL_EDGE: { faceSelections.ClearAll (); for (int i=0; i<mesh.FNum(); i++) { for (int j=0; j<mesh.F(i)->deg; j++) { int edgeIndex = mesh.F(i)->edg[j]; if (mesh.E(edgeIndex)->GetFlag(MN_SEL)) { faceSelections.Set(i); break; } } } break; } } // preserve the existing selection settings oldLevel = mesh.selLevel; mesh.getFaceSel (oldFaceSelections); // set the face selections mesh.ClearFFlags (MN_SEL); mesh.FaceSelect(faceSelections); mesh.selLevel = MNM_SL_FACE; // copy the selected faces and flip Normal direction as needed if (copy) { mesh.CloneFaces(); mesh.freeVSelectionWeights (); } // Now, note that by PolyMesh rules, we can only flip entire selected elements. // So we broaden our selection to include entire elements that are only partially selected: for (int i=0; i<mesh.numf; i++) { if (mesh.f[i].GetFlag (MN_DEAD)) continue; if (!mesh.f[i].GetFlag (MN_SEL)) continue; mesh.PaintFaceFlag (i, MN_SEL); } if (axis<3) { for (i=0; i<mesh.FNum(); i++) { if (mesh.F(i)->GetFlag(MN_SEL)) mesh.FlipNormal(i); } if (mesh.GetFlag (MN_MESH_FILLED_IN)) { // We also need to flip edge normals: for (i=0; i<mesh.ENum(); i++) { if (mesh.f[mesh.e[i].f1].GetFlag (MN_SEL)) { int hold = mesh.e[i].v1; mesh.e[i].v1 = mesh.e[i].v2; mesh.e[i].v2 = hold; } } } } } // support for shape objects else if (os->obj->IsSubClassOf(splineShapeClassID)) { SplineShape *ss = (SplineShape*)os->obj; BezierShape &shape = ss->shape; oldLevel = shape.selLevel; switch (shape.selLevel) { case SHAPE_OBJECT: case SHAPE_VERTEX: shape.selLevel = SHAPE_SPLINE; shape.polySel.SetAll(); break; case SHAPE_SPLINE: case SHAPE_SEGMENT: break; } if (copy) shape.CloneSelectedParts((axis < 3 && splineMethod == SPLINE_REVERSE) ? TRUE : FALSE); } else if(os->obj->SuperClassID() == SHAPE_CLASS_ID) { ShapeObject *so = (ShapeObject *)os->obj; if(so->CanMakeBezier()) { SplineShape *ss = new SplineShape(); so->MakeBezier(t, ss->shape); ss->SetChannelValidity(GEOM_CHAN_NUM, GetValidity(t) & so->ObjectValidity(t)); os->obj = ss; os->obj->UnlockObject(); convertedShape = TRUE; BezierShape &shape = ss->shape; oldLevel = shape.selLevel; switch (shape.selLevel) { case SHAPE_OBJECT: case SHAPE_VERTEX: shape.selLevel = SHAPE_SPLINE; shape.polySel.SetAll(); break; case SHAPE_SPLINE: case SHAPE_SEGMENT: break; } if (copy) shape.CloneSelectedParts((axis < 3 && splineMethod == SPLINE_REVERSE) ? TRUE : FALSE); } } MirrorDeformer deformer(axis,offset,tm,itm); os->obj->Deform(&deformer, TRUE); // if (axis < 3 && splineMethod == SPLINE_REVERSE) { if (os->obj->IsSubClassOf(splineShapeClassID)) { SplineShape *ss = (SplineShape*)os->obj; BezierShape &shape = ss->shape; for (int i = 0; i < shape.bindList.Count(); i++) { int index = 0; int spindex = shape.bindList[i].pointSplineIndex; // Point3 p=shape.splines[spindex]->GetKnot(index).Knot(); if (shape.bindList[i].isEnd) index = shape.splines[spindex]->KnotCount()-1; shape.bindList[i].bindPoint = shape.splines[spindex]->GetKnotPoint(index); shape.bindList[i].segPoint = shape.splines[spindex]->GetKnotPoint(index); } shape.UpdateBindList(TRUE); } else if(os->obj->SuperClassID() == SHAPE_CLASS_ID) { ShapeObject *so = (ShapeObject *)os->obj; if(so->CanMakeBezier()) { SplineShape *ss = new SplineShape(); so->MakeBezier(t, ss->shape); ss->SetChannelValidity(GEOM_CHAN_NUM, GetValidity(t) & so->ObjectValidity(t)); os->obj = ss; os->obj->UnlockObject(); convertedShape = TRUE; BezierShape &shape = ss->shape; for (int i = 0; i < shape.bindList.Count(); i++) { int index = 0; int spindex = shape.bindList[i].pointSplineIndex; // Point3 p; if (shape.bindList[i].isEnd) index = shape.splines[spindex]->KnotCount()-1; shape.bindList[i].bindPoint = shape.splines[spindex]->GetKnotPoint(index); shape.bindList[i].segPoint = shape.splines[spindex]->GetKnotPoint(index); } shape.UpdateBindList(TRUE); } } } os->obj->UpdateValidity(GEOM_CHAN_NUM,GetValidity(t)); // restore the original selections if (os->obj->IsSubClassOf(triObjectClassID)) { TriObject *tobj = (TriObject*)os->obj; tobj->GetMesh().selLevel = oldLevel; } #ifndef NO_PATCHES else if (os->obj->IsSubClassOf(patchObjectClassID)) { PatchObject *pobj = (PatchObject*)os->obj; pobj->GetPatchMesh(t).selLevel = oldLevel; } #endif // NO_PATCHES else if (os->obj->IsSubClassOf(polyObjectClassID)) { PolyObject *pPolyOb = (PolyObject*)os->obj; pPolyOb->GetMesh().selLevel = oldLevel; pPolyOb->GetMesh().dispFlags = 0; switch (oldLevel) { case MNM_SL_VERTEX: pPolyOb->GetMesh().dispFlags = MNDISP_SELVERTS | MNDISP_VERTTICKS; break; case MNM_SL_EDGE: pPolyOb->GetMesh().dispFlags = MNDISP_SELEDGES; break; case MNM_SL_FACE: pPolyOb->GetMesh().dispFlags = MNDISP_SELFACES; break; } pPolyOb->GetMesh().FaceSelect(oldFaceSelections); } else if(os->obj->IsSubClassOf(splineShapeClassID) || convertedShape) { SplineShape *ss = (SplineShape*)os->obj; ss->shape.selLevel = oldLevel; } }
void SubscriberManager::build_patch(PatchObject& po, const AssociatedURIs& associated_uris) { po.set_associated_uris(associated_uris); po.set_increment_cseq(true); }
void SmoothMod::ModifyObject(TimeValue t, ModContext &mc, ObjectState *os, INode *node) { Interval valid = FOREVER; int autoSmooth, bits = 0, prevent = 0; float thresh = 0.0f; pblock->GetValue(sm_autosmooth, t, autoSmooth, valid); if (autoSmooth) { pblock->GetValue(sm_threshold, t, thresh, valid); pblock->GetValue(sm_prevent_indirect, t, prevent, valid); } else { pblock->GetValue(sm_smoothbits, t, bits, valid); } // For version 4 and later, we process patch meshes as they are and pass them on. Earlier // versions converted to TriMeshes (done below). For adding other new types of objects, add // them here! bool done = false; #ifndef NO_PATCHES if(version >= MATMOD_VER4 && os->obj->IsSubClassOf(patchObjectClassID)) { PatchObject *patchOb = (PatchObject *)os->obj; PatchMesh &pmesh = patchOb->GetPatchMesh(t); BOOL useSel = pmesh.selLevel >= PO_PATCH; if (autoSmooth) pmesh.AutoSmooth (thresh, useSel, prevent); else { for (int i=0; i<pmesh.getNumPatches(); i++) { if (!useSel || pmesh.patchSel[i]) pmesh.patches[i].smGroup = (DWORD)bits; } } pmesh.InvalidateGeomCache(); // Do this because there isn't a topo cache in PatchMesh patchOb->UpdateValidity(TOPO_CHAN_NUM,valid); done = true; } #endif // NO_PATCHES if (!done && os->obj->IsSubClassOf (polyObjectClassID)) { PolyObject *pPolyOb = (PolyObject *)os->obj; MNMesh &mesh = pPolyOb->GetMesh(); BOOL useSel = (mesh.selLevel == MNM_SL_FACE); if (autoSmooth) mesh.AutoSmooth (thresh, useSel, prevent); else { for (int faceIndex=0; faceIndex<mesh.FNum(); faceIndex++) { if (!useSel || mesh.F(faceIndex)->GetFlag(MN_SEL)) { mesh.F(faceIndex)->smGroup = (DWORD)bits; } } } // Luna task 747 // We need to rebuild the smoothing-group-based normals in the normalspec, if any: if (mesh.GetSpecifiedNormals()) { mesh.GetSpecifiedNormals()->SetParent (&mesh); mesh.GetSpecifiedNormals()->BuildNormals (); mesh.GetSpecifiedNormals()->ComputeNormals (); } pPolyOb->UpdateValidity(TOPO_CHAN_NUM,valid); done = true; } TriObject *triOb = NULL; if (!done) { if (os->obj->IsSubClassOf(triObjectClassID)) triOb = (TriObject *)os->obj; else { // Convert to triobject if we can. if(os->obj->CanConvertToType(triObjectClassID)) { TriObject *triOb = (TriObject *)os->obj->ConvertToType(t, triObjectClassID); // We'll need to stuff this back into the pipeline: os->obj = triOb; // Convert validities: Interval objValid = os->obj->ChannelValidity (t, TOPO_CHAN_NUM); triOb->SetChannelValidity (TOPO_CHAN_NUM, objValid); triOb->SetChannelValidity (GEOM_CHAN_NUM, objValid & os->obj->ChannelValidity (t, GEOM_CHAN_NUM)); triOb->SetChannelValidity (TEXMAP_CHAN_NUM, objValid & os->obj->ChannelValidity (t, TEXMAP_CHAN_NUM)); triOb->SetChannelValidity (VERT_COLOR_CHAN_NUM, objValid & os->obj->ChannelValidity (t, VERT_COLOR_CHAN_NUM)); triOb->SetChannelValidity (DISP_ATTRIB_CHAN_NUM, objValid & os->obj->ChannelValidity (t, DISP_ATTRIB_CHAN_NUM)); } } } if (triOb) { // one way or another, there's a triobject to smooth. Mesh & mesh = triOb->GetMesh(); BOOL useSel = mesh.selLevel == MESH_FACE; if (autoSmooth) mesh.AutoSmooth (thresh, useSel, prevent); else { for (int i=0; i<mesh.getNumFaces(); i++) { if (!useSel || mesh.faceSel[i]) mesh.faces[i].smGroup = (DWORD)bits; } } triOb->GetMesh().InvalidateTopologyCache(); triOb->UpdateValidity(TOPO_CHAN_NUM,valid); } }
void NormalMod::ModifyObject(TimeValue t, ModContext &mc, ObjectState *os, INode *node) { Interval valid = FOREVER; int flip, unify; pblock->GetValue(PB_FLIP,t,flip,valid); pblock->GetValue(PB_UNIFY,t,unify,valid); // For version 4 and later, we process patch meshes as they are and pass them on. Earlier // versions converted to TriMeshes (done below). For adding other new types of objects, add // them here! #ifndef NO_PATCHES if(version >= MATMOD_VER4 && os->obj->IsSubClassOf(patchObjectClassID)) { PatchObject *patchOb = (PatchObject *)os->obj; PatchMesh &pmesh = patchOb->GetPatchMesh(t); BOOL useSel = pmesh.selLevel >= PO_PATCH; if (unify) pmesh.UnifyNormals(useSel); if (flip) pmesh.FlipPatchNormal(useSel ? -1 : -2); patchOb->UpdateValidity(TOPO_CHAN_NUM,valid); } else // If it's a TriObject, process it #endif // NO_PATCHES if(os->obj->IsSubClassOf(triObjectClassID)) { TriObject *triOb = (TriObject *)os->obj; DoNormalSet(triOb, unify, flip); triOb->UpdateValidity(TOPO_CHAN_NUM,valid); } // Process PolyObjects // note: Since PolyObjects must always have the normals alligned they do not // need to support unify and they do not allow normal flips on selected faces else if(os->obj->IsSubClassOf(polyObjectClassID)) { PolyObject *pPolyOb = (PolyObject *)os->obj; MNMesh& mesh = pPolyOb->GetMesh(); if (flip) { // flip selected faces only if entire elements are selected if (mesh.selLevel == MNM_SL_FACE) { // sca 12/8/2000: Use MNMesh flipping code instead of the code that was here. mesh.FlipElementNormals (MN_SEL); } else { // Flip the entire object if selected elements were not flipped for (int i=0; i<mesh.FNum(); i++) { mesh.f[i].SetFlag (MN_WHATEVER, !mesh.f[i].GetFlag(MN_DEAD)); } mesh.FlipElementNormals (MN_WHATEVER); } // Luna task 747: // We cannot support specified normals here at this time. // NOTE this assumes that both the topo and geo channels are to be freed // this means that the modifier needs to also set the channels changed to // geo and topo otherwise we will be deleting a channel we dont own. mesh.ClearSpecifiedNormals (); } pPolyOb->UpdateValidity(GEOM_CHAN_NUM,valid); pPolyOb->UpdateValidity(TOPO_CHAN_NUM,valid); } else // Fallback position: If it can convert to a TriObject, do it! if(os->obj->CanConvertToType(triObjectClassID)) { TriObject *triOb = (TriObject *)os->obj->ConvertToType(t, triObjectClassID); // Now stuff this into the pipeline! os->obj = triOb; DoNormalSet(triOb, unify, flip); triOb->UpdateValidity(TOPO_CHAN_NUM,valid); } else return; // Do nothing if it can't convert to triObject }
void ExtrudeMod::ModifyObject(TimeValue t, ModContext &mc, ObjectState * os, INode *node) { //DebugPrint(_T("Extrude modifying object\n")); // Get our personal validity interval... Interval valid = GetValidity(t); // and intersect it with the channels we use as input (see ChannelsUsed) valid &= os->obj->ChannelValidity(t,TOPO_CHAN_NUM); valid &= os->obj->ChannelValidity(t,GEOM_CHAN_NUM); int output; pblock->GetValue(PB_OUTPUT, TimeValue(0), output, FOREVER); switch (output) { case NURBS_OUTPUT: #ifndef NO_NURBS { // Here is where all the fun stuff happens -- GenerateExtrudeSurface fills in the EM, // then we stuff the EditableSurface into the pipeline. ShapeObject *shape = (ShapeObject *)os->obj; float amount; BOOL texturing, genMatIds, useShapeIDs; pblock->GetValue(PB_MAPPING, TimeValue(0), texturing, FOREVER); pblock->GetValue(PB_GEN_MATIDS, TimeValue(0), genMatIds, FOREVER); pblock->GetValue(PB_USE_SHAPEIDS, TimeValue(0), useShapeIDs, FOREVER); int levels,capStart,capEnd,capType; pblock->GetValue(PB_SEGS,t,levels,FOREVER); if (levels<1) levels = 1; pblock->GetValue(PB_CAPSTART,t,capStart,FOREVER); pblock->GetValue(PB_CAPEND,t,capEnd,FOREVER); pblock->GetValue(PB_CAPTYPE,t,capType,FOREVER); pblock->GetValue(PB_AMOUNT,t,amount,FOREVER); LimitValue(amount, -1000000.0f, 1000000.0f); BOOL suspended = FALSE; if (theHold.Holding()) { theHold.Suspend(); suspended = TRUE; } Object *nobj = CreateNURBSExtrudeShape(ip, GetString(IDS_RB_EXTRUDE), t, shape, amount, capStart, capEnd, capType, texturing, genMatIds, useShapeIDs); if (suspended) { theHold.Resume(); } // We only set geom validity because we preserve animation on clone // and copying other cahnnels causes problems -- SCM 9/2/97 nobj->SetChannelValidity(GEOM_CHAN_NUM, valid); os->obj = nobj; break;} #endif #ifndef NO_PATCHES case PATCH_OUTPUT: { // Here is where all the fun stuff happens -- BuildPatchFromShape fills in the PatchObject's patch mesh, // then we stuff the PatchObject into the pipeline. PatchObject *pat = new PatchObject; BuildPatchFromShape(t, mc, os, pat->patch); pat->SetChannelValidity(TOPO_CHAN_NUM, valid); pat->SetChannelValidity(GEOM_CHAN_NUM, valid); pat->SetChannelValidity(TEXMAP_CHAN_NUM, valid); pat->SetChannelValidity(MTL_CHAN_NUM, valid); pat->SetChannelValidity(SELECT_CHAN_NUM, valid); pat->SetChannelValidity(SUBSEL_TYPE_CHAN_NUM, valid); pat->SetChannelValidity(DISP_ATTRIB_CHAN_NUM, valid); os->obj = pat; break;} #endif // NO_PATCHES case MESH_OUTPUT: { // Here is where all the fun stuff happens -- BuildMeshFromShape fills in the TriObject's mesh, // then we stuff the TriObj into the pipeline. TriObject *tri = CreateNewTriObject(); BuildMeshFromShape(t, mc, os, tri->GetMesh()); tri->SetChannelValidity(TOPO_CHAN_NUM, valid); tri->SetChannelValidity(GEOM_CHAN_NUM, valid); tri->SetChannelValidity(TEXMAP_CHAN_NUM, valid); tri->SetChannelValidity(MTL_CHAN_NUM, valid); tri->SetChannelValidity(SELECT_CHAN_NUM, valid); tri->SetChannelValidity(SUBSEL_TYPE_CHAN_NUM, valid); tri->SetChannelValidity(DISP_ATTRIB_CHAN_NUM, valid); os->obj = tri; break; } #ifdef XXDESIGN_VER case AMSOLID_OUTPUT: { //Create an extrusion solid using Facet Modeler Object* solid = (Object*)CreateInstance(GEOMOBJECT_CLASS_ID, GENERIC_AMSOLID_CLASS_ID); assert(solid); if(solid) { IGeomImp* cacheptr = (IGeomImp*)(solid->GetInterface(I_GEOMIMP)); assert(cacheptr); if(cacheptr) { bool res = BuildAMSolidFromShape(t, mc, os, cacheptr); solid->ReleaseInterface(I_GEOMIMP, cacheptr); if(!res) { valid.SetInstant(t); // assert(!cacheptr->isNull()); } for(int i=0; i<NUM_OBJ_CHANS;i++) solid->SetChannelValidity(i, valid); os->obj = solid; } } break; } #endif } os->obj->UnlockObject(); }