int MirrorMod::Display( TimeValue t, INode* inode, ViewExp *vpt, int flagst, ModContext *mc) { GraphicsWindow *gw = vpt->getGW(); Point3 pt[4]; Matrix3 tm = CompMatrix(t,inode,mc); int savedLimits; gw->setRndLimits((savedLimits = gw->getRndLimits()) & ~GW_ILLUM); gw->setTransform(tm); if (ip && ip->GetSubObjectLevel() == 1) { //gw->setColor(LINE_COLOR, (float)1.0, (float)1.0, (float)0.0); gw->setColor(LINE_COLOR,GetUIColor(COLOR_SEL_GIZMOS)); } else { //gw->setColor(LINE_COLOR, (float).85, (float).5, (float)0.0); gw->setColor(LINE_COLOR,GetUIColor(COLOR_GIZMOS)); } DrawLineProc lp(gw); DrawGizmo( vpt->GetScreenScaleFactor(tm.GetTrans())*SCREEN_SCALE,lp); gw->setRndLimits(savedLimits); return 0; }
int SymmetryMod::HitTest (TimeValue t, INode* inode, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt, ModContext* mc) { if ( ! vpt || ! vpt->IsAlive() ) { // why are we here DbgAssert(!_T("Invalid viewport!")); return FALSE; } GraphicsWindow *gw = vpt->getGW(); Point3 pt; HitRegion hr; int savedLimits, res = 0; Matrix3 tm = CompMatrix(t,inode,mc); MakeHitRegion(hr,type, crossing,4,p); gw->setHitRegion(&hr); gw->setRndLimits(((savedLimits = gw->getRndLimits()) | GW_PICK) & ~GW_ILLUM); gw->setTransform(tm); gw->clearHitCode(); DrawLineProc lp(gw); DrawGizmo( vpt->GetScreenScaleFactor(tm.GetTrans())*SCREEN_SCALE,lp); gw->setRndLimits(savedLimits); if (gw->checkHitCode()) { vpt->LogHit(inode, mc, gw->getHitDistance(), 0, NULL); return 1; } return 0; }
int FExtrudeMod::HitTest( TimeValue t, INode* inode, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt, ModContext* mc) { if ( ! vpt || ! vpt->IsAlive() ) { // why are we here DbgAssert(!_T("Invalid viewport!")); return FALSE; } GraphicsWindow *gw = vpt->getGW(); Point3 pt; HitRegion hr; int savedLimits, res = 0; Matrix3 tm = CompMatrix(t,inode,mc); MakeHitRegion(hr,type, crossing,4,p); gw->setHitRegion(&hr); gw->setRndLimits(((savedLimits = gw->getRndLimits()) | GW_PICK) & ~GW_ILLUM); gw->setTransform(tm); gw->clearHitCode(); base->GetValue(t,&pt,FOREVER,CTRL_ABSOLUTE); gw->marker(&pt,HOLLOW_BOX_MRKR); if (gw->checkHitCode()) { vpt->LogHit(inode, mc, gw->getHitDistance(), 0, NULL); res = 1; } gw->setRndLimits(savedLimits); return res; }
void MirrorMod::GetSubObjectCenters( SubObjAxisCallback *cb,TimeValue t, INode *node,ModContext *mc) { Matrix3 tm = CompMatrix(t,node,mc); cb->Center(tm.GetTrans(),0); }
int FExtrudeMod::Display( TimeValue t, INode* inode, ViewExp *vpt, int flagst, ModContext *mc) { if ( ! vpt || ! vpt->IsAlive() ) { // why are we here DbgAssert(!_T("Invalid viewport!")); return FALSE; } GraphicsWindow *gw = vpt->getGW(); Point3 pt; Matrix3 tm = CompMatrix(t,inode,mc); int savedLimits; gw->setRndLimits((savedLimits = gw->getRndLimits()) & ~GW_ILLUM); gw->setTransform(tm); // Draw start point if (ip && ip->GetSubObjectLevel() == 1) { //gw->setColor(LINE_COLOR, (float)1.0, (float)1.0, (float)0.0); gw->setColor(LINE_COLOR,GetUIColor(COLOR_SEL_GIZMOS)); } else { //gw->setColor(LINE_COLOR, (float).85, (float).5, (float)0.0); gw->setColor(LINE_COLOR,GetUIColor(COLOR_GIZMOS)); } base->GetValue(t,&pt,FOREVER,CTRL_ABSOLUTE); gw->marker(&pt,HOLLOW_BOX_MRKR); gw->setRndLimits(savedLimits); return 0; }
int SymmetryMod::Display (TimeValue t, INode* inode, ViewExp *vpt, int flagst, ModContext *mc) { if ( ! vpt || ! vpt->IsAlive() ) { // why are we here DbgAssert(!_T("Invalid viewport!")); return FALSE; } GraphicsWindow *gw = vpt->getGW(); Point3 pt[4]; Matrix3 tm = CompMatrix(t,inode,mc); int savedLimits; gw->setRndLimits((savedLimits = gw->getRndLimits()) & ~GW_ILLUM); gw->setTransform(tm); if (mp_ip && mp_ip->GetSubObjectLevel() == 1) { gw->setColor(LINE_COLOR,GetUIColor(COLOR_SEL_GIZMOS)); } else { gw->setColor(LINE_COLOR,GetUIColor(COLOR_GIZMOS)); } DrawLineProc lp(gw); DrawGizmo (vpt->GetScreenScaleFactor(tm.GetTrans())*SCREEN_SCALE,lp); gw->setRndLimits(savedLimits); return 0; }
void FExtrudeMod::GetSubObjectTMs( SubObjAxisCallback *cb,TimeValue t, INode *node,ModContext *mc) { Matrix3 tm = CompMatrix(t,node,mc); cb->TM(tm,0); }
void FExtrudeMod::GetWorldBoundBox (TimeValue t, INode* inode, ViewExp * /*vpt*/, Box3& box, ModContext *mc) { Matrix3 tm = CompMatrix(t,inode,mc); Point3 pt; box.Init(); mp_base->GetValue(t,&pt,FOREVER,CTRL_ABSOLUTE); box += pt * tm; }
void FExtrudeMod::GetSubObjectCenters (SubObjAxisCallback *cb, TimeValue t, INode *node,ModContext *mc) { Matrix3 tm = CompMatrix(t,node,mc); Point3 p; mp_base->GetValue(t,&p,FOREVER,CTRL_ABSOLUTE); tm.PreTranslate(p); cb->Center(tm.GetTrans(),0); }
void MirrorMod::GetWorldBoundBox( TimeValue t,INode* inode, ViewExp *vpt, Box3& box, ModContext *mc) { GraphicsWindow *gw = vpt->getGW(); Matrix3 tm = CompMatrix(t,inode,mc); BoxLineProc bproc(&tm); DrawGizmo( vpt->GetScreenScaleFactor(tm.GetTrans())*SCREEN_SCALE,bproc); box = bproc.Box(); }
void SymmetryMod::GetWorldBoundBox (TimeValue t,INode* inode, ViewExp *vpt, Box3& box, ModContext *mc) { if ( ! vpt || ! vpt->IsAlive() ) { box.Init(); return; } GraphicsWindow *gw = vpt->getGW(); Matrix3 tm = CompMatrix(t,inode,mc); BoxLineProc bproc(&tm); DrawGizmo (vpt->GetScreenScaleFactor(tm.GetTrans())*SCREEN_SCALE, bproc); box = bproc.Box(); }
int AFRMod::HitTest( TimeValue t, INode* inode, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt, ModContext* mc) { GraphicsWindow *gw = vpt->getGW(); Point3 pt; HitRegion hr; int savedLimits, res = 0; Matrix3 tm = CompMatrix(t,inode,mc); MakeHitRegion(hr,type, crossing,4,p); gw->setHitRegion(&hr); gw->setRndLimits(((savedLimits = gw->getRndLimits()) | GW_PICK) & ~GW_ILLUM); gw->setTransform(tm); // Hit test start point if ((flags&HIT_SELONLY && sel[0]) || (flags&HIT_UNSELONLY && !sel[0]) || !(flags&(HIT_UNSELONLY|HIT_SELONLY)) ) { gw->clearHitCode(); p1->GetValue(t,&pt,FOREVER,CTRL_ABSOLUTE); gw->marker(&pt,HOLLOW_BOX_MRKR); if (gw->checkHitCode()) { vpt->LogHit(inode, mc, gw->getHitDistance(), 0, NULL); res = 1; } } // Hit test end point if ((flags&HIT_SELONLY && sel[1]) || (flags&HIT_UNSELONLY && !sel[1]) || !(flags&(HIT_UNSELONLY|HIT_SELONLY)) ) { gw->clearHitCode(); p2->GetValue(t,&pt,FOREVER,CTRL_ABSOLUTE); gw->marker(&pt,HOLLOW_BOX_MRKR); if (gw->checkHitCode()) { vpt->LogHit(inode, mc, gw->getHitDistance(), 1, NULL); res = 1; } } gw->setRndLimits(savedLimits); return res; }
void FExtrudeMod::GetWorldBoundBox( TimeValue t,INode* inode, ViewExp *vpt, Box3& box, ModContext *mc) { if ( ! vpt || ! vpt->IsAlive() ) { // why are we here DbgAssert(!_T("Invalid viewport!")); return; } Matrix3 tm = CompMatrix(t,inode,mc); Point3 pt; box.Init(); base->GetValue(t,&pt,FOREVER,CTRL_ABSOLUTE); box += pt * tm; }
void SymmetryMod::ModifyPolyObject (TimeValue t, ModContext &mc, PolyObject *pobj, INode *inode) { MNMesh &mesh = pobj->GetMesh(); if (mUseRampageWeldMath) mesh.SetFlag(MN_MESH_USE_MAX2012_WELD_MATH,TRUE); // Luna task 747 // We cannot support specified normals in Symmetry at this time. mesh.ClearSpecifiedNormals(); Interval iv = FOREVER; int axis, slice, weld, flip; float thresh; mp_pblock->GetValue (kSymAxis, t, axis, iv); mp_pblock->GetValue (kSymFlip, t, flip, iv); mp_pblock->GetValue (kSymSlice, t, slice, iv); mp_pblock->GetValue (kSymWeld, t, weld, iv); mp_pblock->GetValue (kSymThreshold, t, thresh, iv); if (thresh<0) thresh=0; // Get transform from mp_mirror controller: Matrix3 tm = CompMatrix (t, NULL, &mc, &iv); Matrix3 itm = Inverse (tm); // Get DotProd(N,x)=off plane definition from transform Point3 Axis(0,0,0); Axis[axis] = flip ? -1.0f : 1.0f; Point3 or = tm.GetTrans(); Point3 N = Normalize(tm*Axis - or); float off = DotProd (N, or); if (slice) SlicePolyObject (mesh, N, off); MirrorPolyObject (mesh, axis, tm, itm); if (weld) { WeldPolyObject (mesh, N, off, thresh); RemovePolySpurs (mesh); } pobj->UpdateValidity (GEOM_CHAN_NUM, iv); pobj->UpdateValidity (TOPO_CHAN_NUM, iv); pobj->UpdateValidity (VERT_COLOR_CHAN_NUM, iv); pobj->UpdateValidity (TEXMAP_CHAN_NUM, iv); pobj->UpdateValidity (SELECT_CHAN_NUM, iv); }
void AFRMod::GetSubObjectCenters( SubObjAxisCallback *cb,TimeValue t, INode *node,ModContext *mc) { Matrix3 tm = CompMatrix(t,node,mc); Point3 pt(0,0,0), p; int c=0; if (sel[0]) { p1->GetValue(t,&p,FOREVER,CTRL_ABSOLUTE); pt += p; c++; } if (sel[1]) { p2->GetValue(t,&p,FOREVER,CTRL_ABSOLUTE); pt += p; c++; } if (c) pt /= float(c); tm.PreTranslate(pt); cb->Center(tm.GetTrans(),0); }
void AFRMod::GetWorldBoundBox( TimeValue t,INode* inode, ViewExp *vpt, Box3& box, ModContext *mc) { Matrix3 tm = CompMatrix(t,inode,mc); Point3 pt1, pt2; box.Init(); p1->GetValue(t,&pt1,FOREVER,CTRL_ABSOLUTE); box += pt1 * tm; p2->GetValue(t,&pt2,FOREVER,CTRL_ABSOLUTE); box += pt2 * tm; Matrix3 vtm; vpt->GetAffineTM(vtm); Point3 vz = vtm.GetRow(2) * Inverse(tm); Point3 dp = (pt2-pt1); Point3 v = Normalize(vz^dp) * Length(dp) * 0.2f; box += (pt2 - (0.2f*dp) + v) * tm; box += (pt2 - (0.2f*dp) - v) * tm; v = Normalize(v^dp) * Length(dp) * 0.2f; box += (pt2 - (0.2f*dp) + v) * tm; box += (pt2 - (0.2f*dp) - v) * tm; }
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; } }
int AFRMod::Display( TimeValue t, INode* inode, ViewExp *vpt, int flagst, ModContext *mc) { GraphicsWindow *gw = vpt->getGW(); Point3 pt[4]; Matrix3 tm = CompMatrix(t,inode,mc); int savedLimits; gw->setRndLimits((savedLimits = gw->getRndLimits()) & ~GW_ILLUM); gw->setTransform(tm); // Draw start point if (ip && ip->GetSubObjectLevel() == 1) { if (sel[0]) gw->setColor(LINE_COLOR, (float)1.0, (float)0.0, (float)0.0); else //gw->setColor(LINE_COLOR, (float)1.0, (float)1.0, (float)0.0); gw->setColor(LINE_COLOR,GetUIColor(COLOR_SEL_GIZMOS)); } else { //gw->setColor(LINE_COLOR, (float).85, (float).5, (float)0.0); gw->setColor(LINE_COLOR,GetUIColor(COLOR_GIZMOS)); } p1->GetValue(t,&pt[0],FOREVER,CTRL_ABSOLUTE); gw->marker(&pt[0],HOLLOW_BOX_MRKR); // Draw end point if (ip && ip->GetSubObjectLevel() == 1) { if (sel[1]) gw->setColor(LINE_COLOR, (float)1.0, (float)0.0, (float)0.0); else //gw->setColor(LINE_COLOR, (float)1.0, (float)1.0, (float)0.0); gw->setColor(LINE_COLOR,GetUIColor(COLOR_SEL_GIZMOS)); } else { //gw->setColor(LINE_COLOR, (float).85, (float).5, (float)0.0); gw->setColor(LINE_COLOR,GetUIColor(COLOR_GIZMOS)); } p2->GetValue(t,&pt[1],FOREVER,CTRL_ABSOLUTE); gw->marker(&pt[1],HOLLOW_BOX_MRKR); // Draw a line inbetween if (ip && ip->GetSubObjectLevel() == 1) { //gw->setColor(LINE_COLOR, (float)1.0, (float)1.0, (float)0.0); gw->setColor(LINE_COLOR,GetUIColor(COLOR_SEL_GIZMOS)); } else { //gw->setColor(LINE_COLOR, (float).85, (float).5, (float)0.0); gw->setColor(LINE_COLOR,GetUIColor(COLOR_GIZMOS)); } gw->polyline(2, pt, NULL, NULL, 0, NULL); // Draw arrowhead Matrix3 vtm; vpt->GetAffineTM(vtm); Point3 vz = vtm.GetRow(2) * Inverse(tm); Point3 dp = (pt[1]-pt[0]); Point3 v = Normalize(vz^dp) * Length(dp) * 0.2f; pt[0] = pt[1] - (0.2f*dp) + v; pt[2] = pt[1] - (0.2f*dp) - v; gw->polyline(3, pt, NULL, NULL, 0, NULL); v = Normalize(v^dp) * Length(dp) * 0.2f; pt[0] = pt[1] - (0.2f*dp) + v; pt[2] = pt[1] - (0.2f*dp) - v; gw->polyline(3, pt, NULL, NULL, 0, NULL); gw->setRndLimits(savedLimits); return 0; }
void SymmetryMod::ModifyTriObject (TimeValue t, ModContext &mc, TriObject *tobj, INode *inode) { Mesh &mesh = tobj->GetMesh(); Interval iv = FOREVER; int axis, slice, weld, flip; float threshold; mp_pblock->GetValue (kSymAxis, t, axis, iv); mp_pblock->GetValue (kSymFlip, t, flip, iv); mp_pblock->GetValue (kSymSlice, t, slice, iv); mp_pblock->GetValue (kSymWeld, t, weld, iv); mp_pblock->GetValue (kSymThreshold, t, threshold, iv); if (threshold<0) threshold=0; // Get transform from mirror controller: Matrix3 tm = CompMatrix (t, NULL, &mc, &iv); Matrix3 itm = Inverse (tm); // Get DotProd(N,x)=offset plane definition from transform Point3 Axis(0,0,0); Axis[axis] = flip ? -1.0f : 1.0f; Point3 origin = tm.GetTrans(); Point3 N = Normalize(tm*Axis - origin); float offset = DotProd (N, origin); // Slice operation does not handle NormalSpecs, but it handles mapping channels. // move our mesh normal data to a map channel MeshNormalSpec *pNormals = mesh.GetSpecifiedNormals (); int normalMapChannel = INVALID_NORMALMAPCHANNEL; if (pNormals && pNormals->GetNumFaces()) { pNormals->SetParent(&mesh); //find an empty map channel for (int mp = 0; mp < mesh.getNumMaps(); mp++) { if (!mesh.mapSupport(mp)) { normalMapChannel = mp; mesh.setMapSupport(normalMapChannel,TRUE); MeshMap& map = mesh.Map(normalMapChannel); for (int i = 0; i < map.fnum; i++) { for (int j = 0; j < 3; j++) { unsigned int newID = pNormals->Face(i).GetNormalID(j); map.tf[i].t[j] = newID; } } map.setNumVerts(pNormals->GetNumNormals()); for (int i = 0; i < map.vnum; i++) { map.tv[i] = pNormals->Normal(i); } // make sure nothing is done with MeshNormalSpec (until data is copied back) pNormals->Clear(); break; } } } // Slice off everything below the plane. if (slice) SliceTriObject (mesh, N, offset); MirrorTriObject (mesh, axis, tm, itm,normalMapChannel); if (weld) WeldTriObject (mesh, N, offset, threshold); //now move the normals back if (pNormals && normalMapChannel != -1) { MeshMap& map = mesh.Map(normalMapChannel); pNormals->SetNumFaces(map.fnum); pNormals->SetNumNormals(map.vnum); pNormals->SetAllExplicit(true); BitArray temp; temp.SetSize(map.vnum); temp.SetAll(); pNormals->SpecifyNormals(TRUE,&temp); for (int i = 0; i < map.vnum; i++) { pNormals->GetNormalArray()[i] = map.tv[i]; pNormals->SetNormalExplicit(i,true); } for (int i = 0; i < map.fnum; i++) { for (int j = 0; j < 3; j++) { pNormals->SetNormalIndex(i,j,map.tf[i].t[j]); MeshNormalFace& face = pNormals->Face(i); face.SpecifyAll(true); } } pNormals->SetFlag(MESH_NORMAL_MODIFIER_SUPPORT); for (int i = 0; i < pNormals->GetNumFaces(); i++) { for (int j = 0; j < 3; j++) { int id = pNormals->GetNormalIndex(i,j); } } pNormals->CheckNormals(); pNormals->SetParent(NULL); // Free the map channel mesh.setMapSupport(normalMapChannel,FALSE); } tobj->UpdateValidity (GEOM_CHAN_NUM, iv); tobj->UpdateValidity (TOPO_CHAN_NUM, iv); tobj->UpdateValidity (VERT_COLOR_CHAN_NUM, iv); tobj->UpdateValidity (TEXMAP_CHAN_NUM, iv); tobj->UpdateValidity (SELECT_CHAN_NUM, iv); }