void CrossSectionMouseProc::DrawCrossing(HWND hWnd) { if (mShapeData == NULL) return; BezierShape *shape = mShapeData->TempData(es)->GetShape(ip->GetTime()); if (shape == NULL) return; int polys = mSelectedSplines.Count(); if (polys <= 0) return; Spline3D *spline = shape->GetSpline(mSelectedSplines[polys-1]); int knots = spline->KnotCount(); Point3 p(0.0f, 0.0f, 0.0f); IPoint3 sp; ViewExp *vpt = ip->GetViewport(hWnd); GraphicsWindow *gw = vpt->getGW(); ip->ReleaseViewport(vpt); gw->setTransform(mObjToWorldTM); HDC hdc = GetDC(hWnd); SetROP2(hdc, R2_XORPEN); SetBkMode(hdc, TRANSPARENT); SelectObject(hdc,CreatePen(PS_DOT, 0, ComputeViewportXORDrawColor())); for (int i = 0, j = 0; i < 2 && i <= j; i++, j += (knots-1)) { if (knots > i) p = spline->GetKnotPoint(j); gw->wTransPoint(&p, &sp); MoveToEx(hdc,sp.x,sp.y,NULL); LineTo(hdc,mMouse.x,mMouse.y); } DeleteObject(SelectObject(hdc,GetStockObject(BLACK_PEN))); ReleaseDC(hWnd, hdc); }
bool AlembicCurves::Save(double time, bool bLastFrame) { ESS_PROFILE_FUNC(); //TimeValue ticks = GET_MAX_INTERFACE()->GetTime(); TimeValue ticks = GetTimeValueFromFrame(time); Object *obj = mMaxNode->EvalWorldState(ticks).obj; if(mNumSamples == 0){ bForever = CheckIfObjIsValidForever(obj, ticks); } else{ bool bNewForever = CheckIfObjIsValidForever(obj, ticks); if(bForever && bNewForever != bForever){ ESS_LOG_INFO( "bForever has changed" ); } } SaveMetaData(mMaxNode, this); // check if the spline is animated if(mNumSamples > 0) { if(bForever) { return true; } } AbcG::OCurvesSchema::Sample curvesSample; std::vector<AbcA::int32_t> nbVertices; std::vector<Point3> vertices; std::vector<float> knotVector; std::vector<Abc::uint16_t> orders; if(obj->ClassID() == EDITABLE_SURF_CLASS_ID){ NURBSSet nurbsSet; BOOL success = GetNURBSSet(obj, ticks, nurbsSet, TRUE); AbcG::CurvePeriodicity cPeriod = AbcG::kNonPeriodic; AbcG::CurveType cType = AbcG::kCubic; AbcG::BasisType cBasis = AbcG::kNoBasis; int n = nurbsSet.GetNumObjects(); for(int i=0; i<n; i++){ NURBSObject* pObject = nurbsSet.GetNURBSObject((int)i); //NURBSType type = pObject->GetType(); if(!pObject){ continue; } if( pObject->GetKind() == kNURBSCurve ){ NURBSCurve* pNurbsCurve = (NURBSCurve*)pObject; int degree; int numCVs; NURBSCVTab cvs; int numKnots; NURBSKnotTab knots; pNurbsCurve->GetNURBSData(ticks, degree, numCVs, cvs, numKnots, knots); orders.push_back(degree+1); const int cvsCount = cvs.Count(); const int knotCount = knots.Count(); for(int j=0; j<cvs.Count(); j++){ NURBSControlVertex cv = cvs[j]; double x, y, z; cv.GetPosition(ticks, x, y, z); vertices.push_back( Point3((float)x, (float)y, (float)z) ); } nbVertices.push_back(cvsCount); //skip the first and last entry because Maya and XSI use this format for(int j=1; j<knots.Count()-1; j++){ knotVector.push_back((float)knots[j]); } if(i == 0){ if(pNurbsCurve->IsClosed()){ cPeriod = AbcG::kPeriodic; } } else{ if(pNurbsCurve->IsClosed()){ if(cPeriod != AbcG::kPeriodic){ ESS_LOG_WARNING("Mixed curve wrap types not supported."); } } else{ if(cPeriod != AbcG::kNonPeriodic){ ESS_LOG_WARNING("Mixed curve wrap types not supported."); } } } } } curvesSample.setType(cType); curvesSample.setWrap(cPeriod); curvesSample.setBasis(cBasis); } else { BezierShape beziershape; PolyShape polyShape; bool bBezier = false; // Get a pointer to the spline shpae ShapeObject *pShapeObject = NULL; if (obj->IsShapeObject()) { pShapeObject = reinterpret_cast<ShapeObject *>(obj); } else { return false; } // Determine if we are a bezier shape if (pShapeObject->CanMakeBezier()) { pShapeObject->MakeBezier(ticks, beziershape); bBezier = true; } else { pShapeObject->MakePolyShape(ticks, polyShape); bBezier = false; } // Get the control points //std::vector<Point3> inTangents; //std::vector<Point3> outTangents; if (bBezier) { int oldVerticesCount = (int)vertices.size(); for (int i = 0; i < beziershape.SplineCount(); i += 1) { Spline3D *pSpline = beziershape.GetSpline(i); int knots = pSpline->KnotCount(); for(int ix = 0; ix < knots; ++ix) { Point3 in = pSpline->GetInVec(ix); Point3 p = pSpline->GetKnotPoint(ix); Point3 out = pSpline->GetOutVec(ix); vertices.push_back( p ); //inTangents.push_back( in ); //outTangents.push_back( out ); } int nNumVerticesAdded = (int)vertices.size() - oldVerticesCount; nbVertices.push_back( nNumVerticesAdded ); oldVerticesCount = (int)vertices.size(); } } else { for (int i = 0; i < polyShape.numLines; i += 1) { PolyLine &refLine = polyShape.lines[i]; nbVertices.push_back(refLine.numPts); for (int j = 0; j < refLine.numPts; j += 1) { Point3 p = refLine.pts[j].p; vertices.push_back(p); } } } // set the type + wrapping curvesSample.setType(bBezier ? AbcG::kCubic : AbcG::kLinear); curvesSample.setWrap(pShapeObject->CurveClosed(ticks, 0) ? AbcG::kPeriodic : AbcG::kNonPeriodic); curvesSample.setBasis(AbcG::kNoBasis); } if(nbVertices.size() == 0 || vertices.size() == 0){ ESS_LOG_WARNING("No curve data to export."); return false; } const int vertCount = (int)vertices.size(); // prepare the bounding box Abc::Box3d bbox; // allocate the points and normals std::vector<Abc::V3f> posVec(vertCount); Matrix3 wm = mMaxNode->GetObjTMAfterWSM(ticks); for(int i=0;i<vertCount;i++) { posVec[i] = ConvertMaxPointToAlembicPoint(vertices[i] ); bbox.extendBy(posVec[i]); // Set the archive bounding box if (mJob) { Point3 worldMaxPoint = wm * vertices[i]; Abc::V3f alembicWorldPoint = ConvertMaxPointToAlembicPoint(worldMaxPoint); mJob->GetArchiveBBox().extendBy(alembicWorldPoint); } } if(knotVector.size() > 0 && orders.size() > 0){ if(!mKnotVectorProperty.valid()){ mKnotVectorProperty = Abc::OFloatArrayProperty(mCurvesSchema.getArbGeomParams(), ".knot_vector", mCurvesSchema.getMetaData(), mJob->GetAnimatedTs() ); } mKnotVectorProperty.set(Abc::FloatArraySample(knotVector)); if(!mOrdersProperty.valid()){ mOrdersProperty = Abc::OUInt16ArrayProperty(mCurvesSchema.getArbGeomParams(), ".orders", mCurvesSchema.getMetaData(), mJob->GetAnimatedTs() ); } mOrdersProperty.set(Abc::UInt16ArraySample(orders)); } // store the bbox curvesSample.setSelfBounds(bbox); mCurvesSchema.getChildBoundsProperty().set(bbox); Abc::Int32ArraySample nbVerticesSample(&nbVertices.front(),nbVertices.size()); curvesSample.setCurvesNumVertices(nbVerticesSample); // allocate for the points and normals Abc::P3fArraySample posSample(&posVec.front(),posVec.size()); curvesSample.setPositions(posSample); mCurvesSchema.set(curvesSample); mNumSamples++; return true; }
void SWrapMod::ModifyObject( TimeValue t, ModContext &mc, ObjectState *os, INode *node) { SWrapObject *obj = (SWrapObject *)GetWSMObject(t); INode *pnode; TriObject *towrapOb=NULL;Object *pobj=NULL; if (obj) pnode=obj->custnode; if (obj && nodeRef && pnode) { Interval valid = FOREVER; if (!obj->cmValid.InInterval(t)) { pobj = pnode->EvalWorldState(t).obj; obj->cmValid=pobj->ObjectValidity(t); Matrix3 tm=pnode->GetObjectTM(t,&(obj->cmValid)); TriObject *wrapOb=IsUseable(pobj,t); if (wrapOb) { if (obj->cmesh) delete obj->cmesh; obj->cmesh=new Mesh; obj->cmesh->DeepCopy(&wrapOb->GetMesh(), PART_GEOM|SELECT_CHANNEL|PART_SUBSEL_TYPE|PART_TOPO|TM_CHANNEL); for (int ic=0;ic<obj->cmesh->getNumVerts();ic++) obj->cmesh->verts[ic]=obj->cmesh->verts[ic]*tm; GetVFLst(obj->cmesh,&obj->vnorms,&obj->fnorms); if (wrapOb!=pobj) wrapOb->DeleteThis(); } } if (!obj->cmesh) return; if ((obj->cmesh->getNumVerts()==0)||(obj->cmesh->getNumFaces()==0)) return; // Matrix3 invtm=Inverse(obj->tm); valid=obj->cmValid; Matrix3 ctm; ctm = nodeRef->GetNodeTM(t,&valid); Ray ray; Point3 v=-ctm.GetRow(2); // Matrix3 nooff=invtm;nooff.NoTrans(); ray.dir=v;//*nooff; int selverts; float kdef,standoff; obj->pblock->GetValue(PB_USESELVERTS,t,selverts,valid); obj->pblock->GetValue(PB_KIDEFAULT,t,kdef,valid); obj->pblock->GetValue(PB_STANDOFF,t,standoff,valid); BezierShape stowrapOb; int found=0; Matrix3 towtm(1); if (os->GetTM()) towtm=*(os->GetTM()); Matrix3 invtowtm=Inverse(towtm); Point3 vert; Class_ID cid=os->obj->ClassID(),es=EDITABLE_SURF_CLASS_ID,efp=FITPOINT_PLANE_CLASS_ID,ecv=EDITABLE_CVCURVE_CLASS_ID,ecfp=EDITABLE_FPCURVE_CLASS_ID; if (((cid==EDITABLE_SURF_CLASS_ID)||(cid==FITPOINT_PLANE_CLASS_ID))||((cid==EDITABLE_CVCURVE_CLASS_ID)||(cid==EDITABLE_FPCURVE_CLASS_ID))) { Object* nurbobj=os->obj; int num=nurbobj->NumPoints(); for (int i=0;i<num;i++) { vert=DoIntersect(nurbobj->GetPoint(i)*towtm,ray,obj->cmesh,kdef,standoff,&found,v,obj->vnorms,obj->fnorms); nurbobj->SetPoint(i,(vert*invtowtm)); } } #ifndef NO_PATCHES else if (os->obj->IsSubClassOf(patchObjectClassID)) { PatchObject* patchob=(PatchObject *)os->obj; PatchMesh *pm=&(patchob->patch); int nv=pm->getNumVerts(); BitArray sel = pm->VertSel(); for (int i=0;i<nv;i++) { if (!selverts||sel[i]) { vert=DoIntersect(pm->getVert(i).p*towtm,ray,obj->cmesh,kdef,standoff,&found,v,obj->vnorms,obj->fnorms); vert=vert*invtowtm; pm->setVert(i,vert); } } /* pm->buildLinkages(); pm->computeInteriors(); pm->InvalidateGeomCache();*/ } #endif // NO_PATCHES else if (towrapOb=IsUseable(os->obj,t)) { Point3 tvector; float dist; float *vssel = NULL; if (selverts) vssel = towrapOb->GetMesh().getVSelectionWeights(); for (int i=0;i<towrapOb->GetMesh().getNumVerts();i++) { if ((!selverts)||(towrapOb->GetMesh().vertSel[i]) ||(vssel&&vssel[i])) { vert = DoIntersect(towrapOb->GetMesh().verts[i]*towtm,ray,obj->cmesh,kdef,standoff,&found,v,obj->vnorms,obj->fnorms); vert = vert*invtowtm; if (vssel&&vssel[i]) { tvector = vert - towrapOb->GetMesh().verts[i]; dist = Length(tvector); if ((float)fabs(dist) > EPSILON) tvector = tvector/dist; else tvector = Zero; vert = towrapOb->GetMesh().verts[i] + dist*vssel[i]*tvector; } towrapOb->GetMesh().verts[i] = vert; } } if (towrapOb!=os->obj) towrapOb->DeleteThis(); } else if((os->obj->IsSubClassOf(splineShapeClassID))||(os->obj->CanConvertToType(splineShapeClassID))) { SplineShape *attSplShape = (SplineShape *)os->obj->ConvertToType(t,splineShapeClassID); if (attSplShape) { stowrapOb=attSplShape->shape; for (int poly=0; poly<stowrapOb.splineCount; ++poly) { Spline3D *spline = stowrapOb.GetSpline(poly); int verts = spline->Verts(); int knots = spline->KnotCount(); BitArray sel = stowrapOb.VertexTempSel(poly); Point3 cknot,cknot2; { for(int k=0; k<knots; ++k) { int vert = k * 3 + 1; if (!selverts||sel[vert]) { cknot=DoIntersect(spline->GetKnotPoint(k)*towtm,ray,obj->cmesh,kdef,standoff,&found,v,obj->vnorms,obj->fnorms); attSplShape->shape.SetVert(poly,vert,cknot*invtowtm); if (found) { int knotType = spline->GetKnotType(k); if(knotType & KTYPE_BEZIER) { cknot2= DoIntersect(spline->GetInVec(k)*towtm,ray,obj->cmesh,kdef,standoff,&found,v,obj->vnorms,obj->fnorms); attSplShape->shape.SetVert(poly,vert-1,(found?cknot2:cknot)*invtowtm); cknot2= DoIntersect(spline->GetOutVec(k)*towtm,ray,obj->cmesh,kdef,standoff,&found,v,obj->vnorms,obj->fnorms); attSplShape->shape.SetVert(poly,vert+1,(found?cknot2:cknot)*invtowtm); } } } } } } if (attSplShape!=os->obj) attSplShape->DeleteThis(); } } // os->obj->PointsWereChanged(); os->obj->UpdateValidity(GEOM_CHAN_NUM,valid); // NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE); } }