protected void renderHermiteConic(int i, boolean thisTypeOnly, int tension) { // cartoons, rockets, trace setNeighbors(i); colix = getLeadColix(i); if (!setBioColix(colix)) return; if (setMads(i, thisTypeOnly) || isExport) { try { if ((meshes[i] == null || !meshReady[i]) && !createMesh(i, madBeg, madMid, madEnd, 1, tension)) return; meshes[i].setColix(colix); bsRenderMesh.set(i); return; } catch (Exception e) { bsRenderMesh.clear(i); meshes[i] = null; Logger.error("render mesh error hermiteConic: " + e.toString()); // System.out.println(e.getMessage()); } } if (diameterBeg == 0 && diameterEnd == 0 || wireframeOnly) g3d.drawLineAB(controlPointScreens[i], controlPointScreens[iNext]); else { g3d.fillHermite( isNucleic ? 4 : 7, diameterBeg, diameterMid, diameterEnd, controlPointScreens[iPrev], controlPointScreens[i], controlPointScreens[iNext], controlPointScreens[iNext2]); } }
/** * @param doFill * @param i * @param thisTypeOnly true for Cartoon but not MeshRibbon */ protected void renderHermiteRibbon(boolean doFill, int i, boolean thisTypeOnly) { // cartoons and meshRibbon setNeighbors(i); colix = getLeadColix(i); if (!setBioColix(colix)) return; colixBack = getLeadColixBack(i); if (doFill && (aspectRatio != 0 || isExport)) { if (setMads(i, thisTypeOnly) || isExport) { try { if ((meshes[i] == null || !meshReady[i]) && !createMesh(i, madBeg, madMid, madEnd, aspectRatio, isNucleic ? 4 : 7)) return; meshes[i].setColix(colix); meshes[i].setColixBack(colixBack); bsRenderMesh.set(i); return; } catch (Exception e) { bsRenderMesh.clear(i); meshes[i] = null; Logger.error("render mesh error hermiteRibbon: " + e.toString()); // System.out.println(e.getMessage()); } } } g3d.drawHermite7( doFill, ribbonBorder, (reversed.get(i) ? -1 : 1) * (isNucleic ? 4 : 7), ribbonTopScreens[iPrev], ribbonTopScreens[i], ribbonTopScreens[iNext], ribbonTopScreens[iNext2], ribbonBottomScreens[iPrev], ribbonBottomScreens[i], ribbonBottomScreens[iNext], ribbonBottomScreens[iNext2], (int) aspectRatio, colixBack); }
protected void renderHermiteArrowHead(int i) { // cartoons only colix = getLeadColix(i); if (!setBioColix(colix)) return; colixBack = getLeadColixBack(i); setNeighbors(i); if (setMads(i, false) || isExport) { try { doCap0 = true; doCap1 = false; if ((meshes[i] == null || !meshReady[i]) && !createMesh( i, (int) Math.floor(madBeg * 1.2), (int) Math.floor(madBeg * 0.6), 0, (aspectRatio == 1 ? aspectRatio : aspectRatio / 2), 7)) return; meshes[i].setColix(colix); bsRenderMesh.set(i); return; } catch (Exception e) { bsRenderMesh.clear(i); meshes[i] = null; Logger.error("render mesh error hermiteArrowHead: " + e.toString()); // System.out.println(e.getMessage()); } } P3 cp = controlPoints[i]; V3 wv = wingVectors[i]; calc1Screen(cp, wv, madBeg, .0007f, screenArrowTop); calc1Screen(cp, wv, madBeg, -.0007f, screenArrowBot); calc1Screen(cp, wv, madBeg, 0.001f, screenArrowTopPrev); calc1Screen(cp, wv, madBeg, -0.001f, screenArrowBotPrev); g3d.drawHermite7( true, ribbonBorder, isNucleic ? 4 : 7, screenArrowTopPrev, screenArrowTop, controlPointScreens[iNext], controlPointScreens[iNext2], screenArrowBotPrev, screenArrowBot, controlPointScreens[iNext], controlPointScreens[iNext2], (int) aspectRatio, colixBack); if (ribbonBorder && aspectRatio == 0) { g3d.fillCylinderXYZ( colix, colix, GData.ENDCAPS_SPHERICAL, (exportType == GData.EXPORT_CARTESIAN ? 50 : 3), // may not be right 0.05 screenArrowTop.x, screenArrowTop.y, screenArrowTop.z, screenArrowBot.x, screenArrowBot.y, screenArrowBot.z); } }
/** * @param distance a distance from a plane or point * @param plane a slabbing plane * @param ptCenters a set of atoms to measure distance from * @param vData when not null, this is a query, not an actual slabbing * @param fData vertex values or other data to overlay * @param bsSource TODO * @param meshSurface second surface; not implemented -- still some problems there * @param andCap to cap this off, crudely only * @param doClean compact set - draw only * @param tokType type of slab * @param isGhost translucent slab, so we mark slabbed triangles */ public void getIntersection( float distance, P4 plane, P3[] ptCenters, Lst<P3[]> vData, float[] fData, BS bsSource, MeshSurface meshSurface, boolean andCap, boolean doClean, int tokType, boolean isGhost) { boolean isSlab = (vData == null); P3[] pts = null; if (fData == null) { if (tokType == T.decimal && bsSource != null) { if (vertexSource == null) return; fData = new float[vc]; for (int i = 0; i < vc; i++) if ((fData[i] = vertexSource[i]) == -1) System.out.println("meshsurface hmm"); } else { fData = vvs; } } Map<String, Integer> mapEdge = new Hashtable<String, Integer>(); /* Vector3f vNorm = null; Vector3f vBC = null; Vector3f vAC = null; Point3f[] pts2 = null; Vector3f vTemp3 = null; Point4f planeTemp = null; boolean isMeshIntersect = (meshSurface != null); if (isMeshIntersect) { // NOT IMPLEMENTED vBC = new Vector3f(); vAC = new Vector3f(); vNorm = new Vector3f(); plane = new Point4f(); planeTemp = new Point4f(); vTemp3 = new Vector3f(); pts2 = new Point3f[] { null, new Point3f(), new Point3f() }; } */ if (ptCenters != null || isGhost) andCap = false; // can only cap faces, and no capping of ghosts float[] values = new float[2]; float[] fracs = new float[2]; double absD = Math.abs(distance); float d1, d2, d3, valA, valB, valC; int sourceA = 0, sourceB = 0, sourceC = 0, setA = 0; Lst<int[]> iPts = (andCap ? new Lst<int[]>() : null); if (pc == 0) { for (int i = mergeVertexCount0; i < vc; i++) { if (Float.isNaN(fData[i]) || checkSlab(tokType, vs[i], fData[i], distance, plane, ptCenters, bsSource) > 0) bsSlabDisplay.clear(i); } return; } int iLast = pc; for (int i = mergePolygonCount0; i < iLast; i++) { if (!setABC(i)) continue; BS bsSlab = (bsSlabGhost != null && bsSlabGhost.get(i) ? bsSlabGhost : bsSlabDisplay); int check1 = pis[i][3]; int check2 = (checkCount == 2 ? pis[i][4] : 0); T3 vA = vs[iA]; T3 vB = vs[iB]; T3 vC = vs[iC]; valA = fData[iA]; valB = fData[iB]; valC = fData[iC]; if (vertexSource != null) { sourceA = vertexSource[iA]; sourceB = vertexSource[iB]; sourceC = vertexSource[iC]; } if (vertexSets != null) setA = vertexSets[iA]; d1 = checkSlab( tokType, vA, valA, (bsSource == null ? distance : sourceA), plane, ptCenters, bsSource); d2 = checkSlab( tokType, vB, valB, (bsSource == null ? distance : sourceB), plane, ptCenters, bsSource); d3 = checkSlab( tokType, vC, valC, (bsSource == null ? distance : sourceC), plane, ptCenters, bsSource); int test1 = (d1 != 0 && d1 < 0 ? 1 : 0) + (d2 != 0 && d2 < 0 ? 2 : 0) + (d3 != 0 && d3 < 0 ? 4 : 0); /* if (iA == 955 || iB == 955 || iC == 955) { System.out.println(i + " " + iA + " " + iB + " " + iC + " "+ d1 + " " + d2 + " " + d3 + " " + test1); System.out.println("testing messhsurf "); } */ /* if (isMeshIntersect && test1 != 7 && test1 != 0) { // NOT IMPLEMENTED boolean isOK = (d1 == 0 && d2 * d3 >= 0 || d2 == 0 && (d1 * d3) >= 0 || d3 == 0 && d1 * d2 >= 0); if (isOK) continue; // We have a potential crossing. Now to find the exact point of crossing // the other isosurface. if (checkIntersection(vA, vB, vC, meshSurface, pts2, vNorm, vBC, vAC, plane, planeTemp, vTemp3)) { iD = addIntersectionVertex(pts2[0], 0, sourceA, mapEdge, -1, -1); // have to choose some source addPolygon(iA, iB, iD, check1 & 1, check2, 0, bsSlabDisplay); addPolygon(iD, iB, iC, check1 & 2, check2, 0, bsSlabDisplay); addPolygon(iA, iD, iC, check1 & 4, check2, 0, bsSlabDisplay); test1 = 0; // toss original iLast = polygonCount; } else { // process normally for now // not fully implemented -- need to check other way as well. } } */ switch (test1) { default: case 7: case 0: // all on the same side break; case 1: case 6: // BC on same side if (ptCenters == null) pts = new P3[] { interpolatePoint(vA, vB, -d1, d2, valA, valB, values, fracs, 0), interpolatePoint(vA, vC, -d1, d3, valA, valC, values, fracs, 1) }; else pts = new P3[] { interpolateSphere(vA, vB, -d1, -d2, absD, valA, valB, values, fracs, 0), interpolateSphere(vA, vC, -d1, -d3, absD, valA, valC, values, fracs, 1) }; break; case 2: case 5: // AC on same side if (ptCenters == null) pts = new P3[] { interpolatePoint(vB, vA, -d2, d1, valB, valA, values, fracs, 1), interpolatePoint(vB, vC, -d2, d3, valB, valC, values, fracs, 0) }; else pts = new P3[] { interpolateSphere(vB, vA, -d2, -d1, absD, valB, valA, values, fracs, 1), interpolateSphere(vB, vC, -d2, -d3, absD, valB, valC, values, fracs, 0) }; break; case 3: case 4: // AB on same side need A-C, B-C if (ptCenters == null) pts = new P3[] { interpolatePoint(vC, vA, -d3, d1, valC, valA, values, fracs, 0), interpolatePoint(vC, vB, -d3, d2, valC, valB, values, fracs, 1) }; else pts = new P3[] { interpolateSphere(vC, vA, -d3, -d1, absD, valC, valA, values, fracs, 0), interpolateSphere(vC, vB, -d3, -d2, absD, valC, valB, values, fracs, 1) }; break; } doClear = true; doGhost = isGhost; doCap = andCap; BS bs; // adjust for minor discrepencies // for (int j = 0; j < 2; j++) // if (fracs[j] == 0) // fracs[1 - j] = (fracs[1 - j] < 0.5 ? 0 : 1); if (isSlab) { // iD = iE = -1; switch (test1) { // A // / \ // B---C case 0: // all on the same side -- toss doCap = false; break; case 7: // all on the same side -- keep continue; case 1: case 6: // 0 A 0 // / \ // 0 -------- 1 // / \ // 1 B-------C 1 boolean tossBC = (test1 == 1); if (tossBC || isGhost) { // 1: BC on side to toss -- +tossBC+isGhost -tossBC+isGhost if (!getDE(fracs, 0, iA, iB, iC, tossBC)) break; if (iD < 0) iD = addIntersectionVertex(pts[0], values[0], sourceA, setA, mapEdge, iA, iB); if (iE < 0) iE = addIntersectionVertex(pts[1], values[1], sourceA, setA, mapEdge, iA, iC); bs = (tossBC ? bsSlab : bsSlabGhost); addPolygonV3(iA, iD, iE, check1 & 5 | 2, check2, 0, bs); if (!isGhost) break; } // BC on side to keep -- -tossBC+isGhost, +tossBC+isGhost if (!getDE(fracs, 1, iA, iC, iB, tossBC)) break; bs = (tossBC ? bsSlabGhost : bsSlab); if (iE < 0) { iE = addIntersectionVertex(pts[0], values[0], sourceB, setA, mapEdge, iA, iB); addPolygonV3(iE, iB, iC, check1 & 3, check2, 0, bs); } if (iD < 0) { iD = addIntersectionVertex(pts[1], values[1], sourceC, setA, mapEdge, iA, iC); addPolygonV3(iD, iE, iC, check1 & 4 | 1, check2, 0, bs); } break; case 5: case 2: // A // \/ \ // /\ \ // B--\--C // \ // boolean tossAC = (test1 == 2); if (tossAC || isGhost) { // AC on side to toss if (!getDE(fracs, 0, iB, iC, iA, tossAC)) break; bs = (tossAC ? bsSlab : bsSlabGhost); if (iE < 0) iE = addIntersectionVertex(pts[0], values[0], sourceB, setA, mapEdge, iB, iA); if (iD < 0) iD = addIntersectionVertex(pts[1], values[1], sourceB, setA, mapEdge, iB, iC); addPolygonV3(iE, iB, iD, check1 & 3 | 4, check2, 0, bs); if (!isGhost) break; } // AC on side to keep if (!getDE(fracs, 1, iB, iA, iC, tossAC)) break; bs = (tossAC ? bsSlabGhost : bsSlab); if (iD < 0) { iD = addIntersectionVertex(pts[0], values[0], sourceA, setA, mapEdge, iB, iA); addPolygonV3(iA, iD, iC, check1 & 5, check2, 0, bs); } if (iE < 0) { iE = addIntersectionVertex(pts[1], values[1], sourceC, setA, mapEdge, iB, iC); addPolygonV3(iD, iE, iC, check1 & 2 | 1, check2, 0, bs); } break; case 4: case 3: // A // / \/ // / /\ // B--/--C // / // boolean tossAB = (test1 == 4); if (tossAB || isGhost) { if (!getDE(fracs, 0, iC, iA, iB, tossAB)) break; if (iD < 0) iD = addIntersectionVertex(pts[0], values[0], sourceC, setA, mapEdge, iA, iC); // CA if (iE < 0) iE = addIntersectionVertex(pts[1], values[1], sourceC, setA, mapEdge, iB, iC); // CB bs = (tossAB ? bsSlab : bsSlabGhost); addPolygonV3(iD, iE, iC, check1 & 6 | 1, check2, 0, bs); if (!isGhost) break; } // AB on side to keep if (!getDE(fracs, 1, iC, iB, iA, tossAB)) break; bs = (tossAB ? bsSlabGhost : bsSlab); if (iE < 0) { iE = addIntersectionVertex(pts[0], values[0], sourceA, setA, mapEdge, iA, iC); // CA addPolygonV3(iA, iB, iE, check1 & 5, check2, 0, bs); } if (iD < 0) { iD = addIntersectionVertex(pts[1], values[1], sourceB, setA, mapEdge, iB, iC); // CB addPolygonV3(iE, iB, iD, check1 & 2 | 4, check2, 0, bs); } break; } if (doClear) { bsSlab.clear(i); if (doGhost) bsSlabGhost.set(i); } if (doCap) { iPts.addLast(new int[] {iD, iE}); } } else if (pts != null) { vData.addLast(pts); } } if (andCap && iPts.size() > 0) { P3 center = new P3(); for (int i = iPts.size(); --i >= 0; ) { int[] ipts = iPts.get(i); center.add(vs[ipts[0]]); center.add(vs[ipts[1]]); } center.scale(0.5f / iPts.size()); int v0 = addIntersectionVertex(center, 0, -1, setA, mapEdge, -1, -1); for (int i = iPts.size(); --i >= 0; ) { int[] ipts = iPts.get(i); // int p = addPolygonV3(ipts[0], v0, ipts[1], 0, 0, 0, bsSlabDisplay); } } if (!doClean) return; BS bsv = new BS(); BS bsp = new BS(); for (int i = 0; i < pc; i++) { if (pis[i] == null) continue; bsp.set(i); for (int j = 0; j < 3; j++) bsv.set(pis[i][j]); } int n = 0; int nPoly = bsp.cardinality(); if (nPoly != pc) { int[] map = new int[vc]; for (int i = 0; i < vc; i++) if (bsv.get(i)) map[i] = n++; T3[] vTemp = new P3[n]; n = 0; for (int i = 0; i < vc; i++) if (bsv.get(i)) vTemp[n++] = vs[i]; int[][] pTemp = AU.newInt2(nPoly); nPoly = 0; for (int i = 0; i < pc; i++) if (pis[i] != null) { for (int j = 0; j < 3; j++) pis[i][j] = map[pis[i][j]]; pTemp[nPoly++] = pis[i]; } vs = vTemp; vc = n; pis = pTemp; pc = nPoly; } }