void Surface :: DefineTangentialPlane (const Point<3> & ap1, const Point<3> & ap2) { p1 = ap1; p2 = ap2; ez = GetNormalVector (p1); ex = p2 - p1; ex -= (ex * ez) * ez; ex.Normalize(); ey = Cross (ez, ex); }
void Block :: DrawSide( Point3Df aP1, Point3Df aP2, Point3Df aP3, Point3Df aP4 ) { glEnable(GL_NORMALIZE); Point3Df NormalVector = GetNormalVector( aP1, aP3, aP2 ); glBegin( GL_QUADS ); glNormal3f( NormalVector.mX, NormalVector.mY, NormalVector.mZ ); glVertex3f( aP1.mX, aP1.mY, aP1.mZ ); glVertex3f( aP2.mX, aP2.mY, aP2.mZ ); glVertex3f( aP3.mX, aP3.mY, aP3.mZ ); glVertex3f( aP4.mX, aP4.mY, aP4.mZ ); glEnd(); }
void Surface :: ToPlane (const Point<3> & p3d, Point<2> & pplane, double h, int & zone) const { Vec<3> p1p, n; n = GetNormalVector (p3d); if (n * ez < 0) { zone = -1; pplane(0) = 1e8; pplane(1) = 1e9; return; } p1p = p3d - p1; pplane(0) = (p1p * ex) / h; pplane(1) = (p1p * ey) / h; zone = 0; }
void InitNormal() { D3DLVERTEX *pv; WORD *pi = NULL; g_pvtxBuff1->Lock(0, 0, (void**)&pv, 0); g_pidxBuff1->Lock(0, 0, (void**)&pi, 0); for (int i=0; i < indexSize; i+=3) { Vector3 v1 = pv[ pi[i]].v; Vector3 v2 = pv[ pi[i+1]].v; Vector3 v3 = pv[ pi[i+2]].v; Vector3 n = GetNormalVector(v1, v2, v3); pv[ pi[i]].n = n; pv[ pi[i+1]].n = n; pv[ pi[i+2]].n = n; } g_pvtxBuff1->Unlock(); g_pidxBuff1->Unlock(); }
void OCCSurface :: ToPlane (const Point<3> & p3d, const PointGeomInfo & geominfo, Point<2> & pplane, double h, int & zone) const { if (projecttype == PLANESPACE) { Vec<3> p1p, n; GetNormalVector (p3d, geominfo, n); p1p = p3d - p1; pplane(0) = (p1p * ex) / h; pplane(1) = (p1p * ey) / h; if (n * nmid < 0) zone = -1; else zone = 0; /* if(zone == -1) { (*testout) << "zone = -1 for " << p3d << " 2D: " << pplane << " n " << n << " nmid " << nmid << endl; glob_testout = true; GetNormalVector (p3d, geominfo, n); glob_testout = false; } */ } else { pplane = Point<2>(geominfo.u, geominfo.v); // (*testout) << "(u,v) = " << geominfo.u << ", " << geominfo.v << endl; pplane = Point<2> (1/h * (Amatinv * (pplane-psp1))); // pplane = Point<2> (h * (Amatinv * (pplane-psp1))); // pplane = Point<2> (1/h * ((pplane-psp1))); zone = 0; }; }
void OCCSurface :: DefineTangentialPlane (const Point<3> & ap1, const PointGeomInfo & geominfo1, const Point<3> & ap2, const PointGeomInfo & geominfo2) { if (projecttype == PLANESPACE) { p1 = ap1; p2 = ap2; //cout << "p1 = " << p1 << endl; //cout << "p2 = " << p2 << endl; GetNormalVector (p1, geominfo1, ez); ex = p2 - p1; ex -= (ex * ez) * ez; ex.Normalize(); ey = Cross (ez, ex); GetNormalVector (p2, geominfo2, n2); nmid = 0.5*(n2+ez); ez = nmid; ez.Normalize(); ex = (p2 - p1).Normalize(); ez -= (ez * ex) * ex; ez.Normalize(); ey = Cross (ez, ex); nmid = ez; //cout << "ex " << ex << " ey " << ey << " ez " << ez << endl; } else { if ( (geominfo1.u < umin) || (geominfo1.u > umax) || (geominfo2.u < umin) || (geominfo2.u > umax) || (geominfo1.v < vmin) || (geominfo1.v > vmax) || (geominfo2.v < vmin) || (geominfo2.v > vmax) ) throw UVBoundsException(); p1 = ap1; p2 = ap2; psp1 = Point<2>(geominfo1.u, geominfo1.v); psp2 = Point<2>(geominfo2.u, geominfo2.v); Vec<3> n; GetNormalVector (p1, geominfo1, n); gp_Pnt pnt; gp_Vec du, dv; occface->D1 (geominfo1.u, geominfo1.v, pnt, du, dv); DenseMatrix D1(3,2), D1T(2,3), DDTinv(2,2); D1(0,0) = du.X(); D1(1,0) = du.Y(); D1(2,0) = du.Z(); D1(0,1) = dv.X(); D1(1,1) = dv.Y(); D1(2,1) = dv.Z(); /* (*testout) << "DefineTangentialPlane" << endl << "---------------------" << endl; (*testout) << "D1 = " << endl << D1 << endl; */ Transpose (D1, D1T); DenseMatrix D1TD1(3,3); D1TD1 = D1T*D1; if (D1TD1.Det() == 0) throw SingularMatrixException(); CalcInverse (D1TD1, DDTinv); DenseMatrix Y(3,2); Vec<3> y1 = (ap2-ap1).Normalize(); Vec<3> y2 = Cross(n, y1).Normalize(); for (int i = 0; i < 3; i++) { Y(i,0) = y1(i); Y(i,1) = y2(i); } DenseMatrix A(2,2); A = DDTinv * D1T * Y; DenseMatrix Ainv(2,2); if (A.Det() == 0) throw SingularMatrixException(); CalcInverse (A, Ainv); for (int i = 0; i < 2; i++) for (int j = 0; j < 2; j++) { Amat(i,j) = A(i,j); Amatinv(i,j) = Ainv(i,j); } Vec<2> temp = Amatinv * (psp2-psp1); double r = temp.Length(); // double alpha = -acos (temp(0)/r); double alpha = -atan2 (temp(1),temp(0)); DenseMatrix R(2,2); R(0,0) = cos (alpha); R(1,0) = -sin (alpha); R(0,1) = sin (alpha); R(1,1) = cos (alpha); A = A*R; if (A.Det() == 0) throw SingularMatrixException(); CalcInverse (A, Ainv); for (int i = 0; i < 2; i++) for (int j = 0; j < 2; j++) { Amat(i,j) = A(i,j); Amatinv(i,j) = Ainv(i,j); } temp = Amatinv * (psp2-psp1); }; }
void MeshOptimize2d :: GenericImprove (Mesh & mesh) { if (!faceindex) { if (writestatus) PrintMessage (3, "Generic Improve"); for (faceindex = 1; faceindex <= mesh.GetNFD(); faceindex++) GenericImprove (mesh); faceindex = 0; } // int j, k, l, ri; int np = mesh.GetNP(); int ne = mesh.GetNSE(); // SurfaceElementIndex sei; // for (SurfaceElementIndex sei = 0; sei < ne; sei++) // { // const Element2d & el = mesh[sei]; // (*testout) << "element " << sei << ": " <<flush; // for(int j=0; j<el.GetNP(); j++) // (*testout) << el[j] << " " << flush; // (*testout) << "IsDeleted() " << el.IsDeleted()<< endl; // } bool ok; int olddef, newdef; ARRAY<ImprovementRule*> rules; ARRAY<SurfaceElementIndex> elmap; ARRAY<int> elrot; ARRAY<PointIndex> pmap; ARRAY<PointGeomInfo> pgi; int surfnr = mesh.GetFaceDescriptor (faceindex).SurfNr(); ImprovementRule * r1; // 2 triangles to quad r1 = new ImprovementRule; r1->oldels.Append (Element2d (1, 2, 3)); r1->oldels.Append (Element2d (3, 2, 4)); r1->newels.Append (Element2d (1, 2, 4, 3)); r1->deledges.Append (INDEX_2 (2,3)); r1->onp = 4; r1->bonus = 2; rules.Append (r1); // 2 quad to 1 quad r1 = new ImprovementRule; r1->oldels.Append (Element2d (1, 2, 3, 4)); r1->oldels.Append (Element2d (4, 3, 2, 5)); r1->newels.Append (Element2d (1, 2, 5, 4)); r1->deledges.Append (INDEX_2 (2, 3)); r1->deledges.Append (INDEX_2 (3, 4)); r1->onp = 5; r1->bonus = 0; rules.Append (r1); // swap quads r1 = new ImprovementRule; r1->oldels.Append (Element2d (1, 2, 3, 4)); r1->oldels.Append (Element2d (3, 2, 5, 6)); r1->newels.Append (Element2d (1, 6, 3, 4)); r1->newels.Append (Element2d (1, 2, 5, 6)); r1->deledges.Append (INDEX_2 (2, 3)); r1->onp = 6; r1->bonus = 0; rules.Append (r1); // three quads to 2 r1 = new ImprovementRule; r1->oldels.Append (Element2d (1, 2, 3, 4)); r1->oldels.Append (Element2d (2, 5, 6, 3)); r1->oldels.Append (Element2d (3, 6, 7, 4)); r1->newels.Append (Element2d (1, 2, 5, 4)); r1->newels.Append (Element2d (4, 5, 6, 7)); r1->deledges.Append (INDEX_2 (2, 3)); r1->deledges.Append (INDEX_2 (3, 4)); r1->deledges.Append (INDEX_2 (3, 6)); r1->onp = 7; r1->bonus = -1; rules.Append (r1); // quad + 2 connected trigs to quad r1 = new ImprovementRule; r1->oldels.Append (Element2d (1, 2, 3, 4)); r1->oldels.Append (Element2d (2, 5, 3)); r1->oldels.Append (Element2d (3, 5, 4)); r1->newels.Append (Element2d (1, 2, 5, 4)); r1->deledges.Append (INDEX_2 (2, 3)); r1->deledges.Append (INDEX_2 (3, 4)); r1->deledges.Append (INDEX_2 (3, 5)); r1->onp = 5; r1->bonus = 0; rules.Append (r1); // quad + 2 non-connected trigs to quad (a and b) r1 = new ImprovementRule; r1->oldels.Append (Element2d (1, 2, 3, 4)); r1->oldels.Append (Element2d (2, 6, 3)); r1->oldels.Append (Element2d (1, 4, 5)); r1->newels.Append (Element2d (1, 3, 4, 5)); r1->newels.Append (Element2d (1, 2, 6, 3)); r1->deledges.Append (INDEX_2 (1, 4)); r1->deledges.Append (INDEX_2 (2, 3)); r1->onp = 6; r1->bonus = 0; rules.Append (r1); r1 = new ImprovementRule; r1->oldels.Append (Element2d (1, 2, 3, 4)); r1->oldels.Append (Element2d (2, 6, 3)); r1->oldels.Append (Element2d (1, 4, 5)); r1->newels.Append (Element2d (1, 2, 4, 5)); r1->newels.Append (Element2d (4, 2, 6, 3)); r1->deledges.Append (INDEX_2 (1, 4)); r1->deledges.Append (INDEX_2 (2, 3)); r1->onp = 6; r1->bonus = 0; rules.Append (r1); // two quad + trig -> one quad + trig r1 = new ImprovementRule; r1->oldels.Append (Element2d (1, 2, 3, 4)); r1->oldels.Append (Element2d (2, 5, 6, 3)); r1->oldels.Append (Element2d (4, 3, 6)); r1->newels.Append (Element2d (1, 2, 6, 4)); r1->newels.Append (Element2d (2, 5, 6)); r1->deledges.Append (INDEX_2 (2, 3)); r1->deledges.Append (INDEX_2 (3, 4)); r1->deledges.Append (INDEX_2 (3, 6)); r1->onp = 6; r1->bonus = -1; rules.Append (r1); // swap quad + trig (a and b) r1 = new ImprovementRule; r1->oldels.Append (Element2d (1, 2, 3, 4)); r1->oldels.Append (Element2d (2, 5, 3)); r1->newels.Append (Element2d (2, 5, 3, 4)); r1->newels.Append (Element2d (1, 2, 4)); r1->deledges.Append (INDEX_2 (2, 3)); r1->onp = 5; r1->bonus = 0; rules.Append (r1); r1 = new ImprovementRule; r1->oldels.Append (Element2d (1, 2, 3, 4)); r1->oldels.Append (Element2d (2, 5, 3)); r1->newels.Append (Element2d (1, 2, 5, 3)); r1->newels.Append (Element2d (1, 3, 4)); r1->deledges.Append (INDEX_2 (2, 3)); r1->onp = 5; r1->bonus = 0; rules.Append (r1); // 2 quads to quad + 2 trigs r1 = new ImprovementRule; r1->oldels.Append (Element2d (1, 2, 3, 4)); r1->oldels.Append (Element2d (3, 2, 5, 6)); r1->newels.Append (Element2d (1, 5, 6, 4)); r1->newels.Append (Element2d (1, 2, 5)); r1->newels.Append (Element2d (4, 6, 3)); r1->deledges.Append (INDEX_2 (2, 3)); r1->onp = 6; r1->bonus = 0; // rules.Append (r1); ARRAY<int> mapped(rules.Size()); ARRAY<int> used(rules.Size()); used = 0; mapped = 0; for (int ri = 0; ri < rules.Size(); ri++) { ImprovementRule & rule = *rules[ri]; rule.incelsonnode.SetSize (rule.onp); rule.reused.SetSize (rule.onp); for (int j = 1; j <= rule.onp; j++) { rule.incelsonnode.Elem(j) = 0; rule.reused.Elem(j) = 0; } for (int j = 1; j <= rule.oldels.Size(); j++) { const Element2d & el = rule.oldels.Elem(j); for (int k = 1; k <= el.GetNP(); k++) rule.incelsonnode.Elem(el.PNum(k))--; } for (int j = 1; j <= rule.newels.Size(); j++) { const Element2d & el = rule.newels.Elem(j); for (int k = 1; k <= el.GetNP(); k++) { rule.incelsonnode.Elem(el.PNum(k))++; rule.reused.Elem(el.PNum(k)) = 1; } } } TABLE<int,PointIndex::BASE> elonnode(np); ARRAY<int,PointIndex::BASE> nelonnode(np); TABLE<SurfaceElementIndex> nbels(ne); nelonnode = -4; for (SurfaceElementIndex sei = 0; sei < ne; sei++) { const Element2d & el = mesh[sei]; if (el.GetIndex() == faceindex && !el.IsDeleted()) { for (int j = 0; j < el.GetNP(); j++) elonnode.Add (el[j], sei); } if(!el.IsDeleted()) { for (int j = 0; j < el.GetNP(); j++) nelonnode[el[j]]++; } } for (SurfaceElementIndex sei = 0; sei < ne; sei++) { const Element2d & el = mesh[sei]; if (el.GetIndex() == faceindex && !el.IsDeleted()) { for (int j = 0; j < el.GetNP(); j++) { for (int k = 0; k < elonnode[el[j]].Size(); k++) { int nbel = elonnode[el[j]] [k]; bool inuse = false; for (int l = 0; l < nbels[sei].Size(); l++) if (nbels[sei][l] == nbel) inuse = true; if (!inuse) nbels.Add (sei, nbel); } } } } for (int ri = 0; ri < rules.Size(); ri++) { const ImprovementRule & rule = *rules[ri]; elmap.SetSize (rule.oldels.Size()); elrot.SetSize (rule.oldels.Size()); pmap.SetSize (rule.onp); pgi.SetSize (rule.onp); for (SurfaceElementIndex sei = 0; sei < ne; sei++) { if (multithread.terminate) break; if (mesh[sei].IsDeleted()) continue; elmap[0] = sei; FlatArray<SurfaceElementIndex> neighbours = nbels[sei]; for (elrot[0] = 0; elrot[0] < mesh[sei].GetNP(); elrot[0]++) { const Element2d & el0 = mesh[sei]; const Element2d & rel0 = rule.oldels[0]; if (el0.GetIndex() != faceindex) continue; if (el0.IsDeleted()) continue; if (el0.GetNP() != rel0.GetNP()) continue; pmap = -1; for (int k = 0; k < el0.GetNP(); k++) { pmap.Elem(rel0[k]) = el0.PNumMod(k+elrot[0]+1); pgi.Elem(rel0[k]) = el0.GeomInfoPiMod(k+elrot[0]+1); } ok = 1; for (int i = 1; i < elmap.Size(); i++) { // try to find a mapping for reference-element i const Element2d & rel = rule.oldels[i]; bool possible = 0; for (elmap[i] = 0; elmap[i] < neighbours.Size(); elmap[i]++) { const Element2d & el = mesh[neighbours[elmap[i]]]; if (el.IsDeleted()) continue; if (el.GetNP() != rel.GetNP()) continue; for (elrot[i] = 0; elrot[i] < rel.GetNP(); elrot[i]++) { possible = 1; for (int k = 0; k < rel.GetNP(); k++) if (pmap.Elem(rel[k]) != -1 && pmap.Elem(rel[k]) != el.PNumMod (k+elrot[i]+1)) possible = 0; if (possible) { for (int k = 0; k < el.GetNP(); k++) { pmap.Elem(rel[k]) = el.PNumMod(k+elrot[i]+1); pgi.Elem(rel[k]) = el.GeomInfoPiMod(k+elrot[i]+1); } break; } } if (possible) break; } if (!possible) { ok = 0; break; } elmap[i] = neighbours[elmap[i]]; } for(int i=0; ok && i<rule.deledges.Size(); i++) { ok = !mesh.IsSegment(pmap.Elem(rule.deledges[i].I1()), pmap.Elem(rule.deledges[i].I2())); } if (!ok) continue; mapped[ri]++; olddef = 0; for (int j = 1; j <= pmap.Size(); j++) olddef += sqr (nelonnode[pmap.Get(j)]); olddef += rule.bonus; newdef = 0; for (int j = 1; j <= pmap.Size(); j++) if (rule.reused.Get(j)) newdef += sqr (nelonnode[pmap.Get(j)] + rule.incelsonnode.Get(j)); if (newdef > olddef) continue; // calc metric badness double bad1 = 0, bad2 = 0; Vec<3> n; SelectSurfaceOfPoint (mesh.Point(pmap.Get(1)), pgi.Get(1)); GetNormalVector (surfnr, mesh.Point(pmap.Get(1)), pgi.Elem(1), n); for (int j = 1; j <= rule.oldels.Size(); j++) bad1 += mesh.SurfaceElement(elmap.Get(j)).CalcJacobianBadness (mesh.Points(), n); // check new element: for (int j = 1; j <= rule.newels.Size(); j++) { const Element2d & rnel = rule.newels.Get(j); Element2d nel(rnel.GetNP()); for (int k = 1; k <= rnel.GetNP(); k++) nel.PNum(k) = pmap.Get(rnel.PNum(k)); bad2 += nel.CalcJacobianBadness (mesh.Points(), n); } if (bad2 > 1e3) continue; if (newdef == olddef && bad2 > bad1) continue; // generate new element: for (int j = 1; j <= rule.newels.Size(); j++) { const Element2d & rnel = rule.newels.Get(j); Element2d nel(rnel.GetNP()); nel.SetIndex (faceindex); for (int k = 1; k <= rnel.GetNP(); k++) { nel.PNum(k) = pmap.Get(rnel.PNum(k)); nel.GeomInfoPi(k) = pgi.Get(rnel.PNum(k)); } mesh.AddSurfaceElement(nel); } for (int j = 0; j < rule.oldels.Size(); j++) mesh.DeleteSurfaceElement ( elmap[j] ); for (int j = 1; j <= pmap.Size(); j++) nelonnode[pmap.Get(j)] += rule.incelsonnode.Get(j); used[ri]++; } } } mesh.Compress(); for (int ri = 0; ri < rules.Size(); ri++) { PrintMessage (5, "rule ", ri+1, " ", mapped[ri], "/", used[ri], " mapped/used"); } }