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]); } }
private void getStateAtoms(SB sb) { BS bsDone = new BS(); Map<String, BS> temp = new Hashtable<String, BS>(); Map<String, BS> temp2 = new Hashtable<String, BS>(); for (Ellipsoid e : atomEllipsoids.values()) { int iType = e.tensor.iType; if (bsDone.get(iType + 1)) continue; bsDone.set(iType + 1); boolean isADP = (e.tensor.iType == Tensor.TYPE_ADP); String cmd = (isADP ? null : "Ellipsoids set " + PT.esc(e.tensor.type)); for (Ellipsoid e2 : atomEllipsoids.values()) { if (e2.tensor.iType != iType || isADP && !e2.isOn) continue; int i = e2.tensor.atomIndex1; // BSUtil.setMapBitSet( temp, i, i, (isADP ? "Ellipsoids " + e2.percent : cmd + " scale " + e2.scale + (e2.options == null ? "" : " options " + PT.esc(e2.options)) + (e2.isOn ? " ON" : " OFF"))); if (e2.colix != C.INHERIT_ALL) BSUtil.setMapBitSet( temp2, i, i, getColorCommand(cmd, e2.pid, e2.colix, translucentAllowed)); } } sb.append(vwr.getCommands(temp, temp2, "select")); }
@Override protected BS getVoxelBitSet(int nPoints) throws Exception { if (bsVoxelBitSet != null) return bsVoxelBitSet; BS bs = new BS(); int bsVoxelPtr = 0; if (surfaceDataCount <= 0) return bs; // unnecessary -- probably a plane or color density int nThisValue = 0; while (bsVoxelPtr < nPoints) { nThisValue = parseInt(); if (nThisValue == Integer.MIN_VALUE) { readLine(); // note -- does not allow for empty lines; // must be a continuous block of numbers. if (line == null || (nThisValue = parseIntStr(line)) == Integer.MIN_VALUE) { if (!endOfData) Logger.error("end of file in JvxlReader?" + " line=" + line); endOfData = true; nThisValue = 10000; // throw new NullPointerException(); } } thisInside = !thisInside; ++jvxlNSurfaceInts; if (thisInside) bs.setBits(bsVoxelPtr, bsVoxelPtr + nThisValue); bsVoxelPtr += nThisValue; } return bs; }
@Override public boolean hasNext() { if (ibond == bondCount) return false; while ((bond = bonds[ibond++]) == null || (bsAtoms != null && (!bsAtoms.get(bond.atomIndex1) || !bsAtoms.get(bond.atomIndex2)))) if (ibond == bondCount) return false; return true; }
private void renderMeshes() { for (int i = bsRenderMesh.nextSetBit(0); i >= 0; i = bsRenderMesh.nextSetBit(i + 1)) { if (meshes[i].normalsTemp != null) { meshes[i].setNormixes(meshes[i].normalsTemp); meshes[i].normalsTemp = null; } else if (meshes[i].normixes == null) { meshes[i].initialize(T.frontlit, null, null); } renderMesh(meshes[i]); } }
// called by JMolSelectionListener.java to set the selected Atoms list public void setSelectedAtoms(BS values) { // System.out.println("Selected: " + values); if (selectedAtoms == null) selectedAtoms = new ArrayList<Atom>(); else selectedAtoms.clear(); String[] valueGet = values.toString().split("[{ }]"); if (modelList != null) { Model currentModel = modelList.get(viewer.getDisplayModelIndex()); for (int i = 0; i < valueGet.length; i++) { if (valueGet[i].compareTo("") != 0) { // if its list of continuous atoms if (valueGet[i].contains(":")) { int start = Integer.parseInt(valueGet[i].split(":")[0]) + 1; int end = Integer.parseInt(valueGet[i].split(":")[1]) + 1; for (int j = start; j <= end; j++) { selectedAtoms.add(currentModel.getAtomHash().get(currentModel.getModelName() + j)); } } else { selectedAtoms.add( currentModel .getAtomHash() .get(currentModel.getModelName() + (Integer.parseInt(valueGet[i]) + 1))); } } } } }
private boolean initializePolymer(BioShape bioShape) { BS bsDeleted = vwr.getDeletedAtoms(); if (vwr.ms.isJmolDataFrameForModel(bioShape.modelIndex)) { controlPoints = bioShape.bioPolymer.getControlPoints(true, 0, false); } else { controlPoints = bioShape.bioPolymer.getControlPoints(isTraceAlpha, sheetSmoothing, invalidateSheets); } monomerCount = bioShape.monomerCount; bsRenderMesh = BS.newN(monomerCount); monomers = bioShape.monomers; reversed = bioShape.bioPolymer.reversed; leadAtomIndices = bioShape.bioPolymer.getLeadAtomIndices(); bsVisible.clearAll(); boolean haveVisible = false; if (invalidateMesh) bioShape.falsifyMesh(); for (int i = monomerCount; --i >= 0; ) { if ((monomers[i].shapeVisibilityFlags & myVisibilityFlag) == 0 || ms.isAtomHidden(leadAtomIndices[i]) || bsDeleted != null && bsDeleted.get(leadAtomIndices[i])) continue; Atom lead = ms.at[leadAtomIndices[i]]; if (!g3d.isInDisplayRange(lead.sX, lead.sY)) continue; bsVisible.set(i); haveVisible = true; } if (!haveVisible) return false; ribbonBorder = vwr.getBoolean(T.ribbonborder); // note that we are not treating a PhosphorusPolymer // as nucleic because we are not calculating the wing // vector correctly. // if/when we do that then this test will become // isNucleic = bioShape.bioPolymer.isNucleic(); isNucleic = bioShape.bioPolymer instanceof NucleicPolymer; isCarbohydrate = bioShape.bioPolymer instanceof CarbohydratePolymer; haveControlPointScreens = false; wingVectors = bioShape.wingVectors; meshReady = bioShape.meshReady; meshes = bioShape.meshes; mads = bioShape.mads; colixes = bioShape.colixes; colixesBack = bioShape.colixesBack; setStructureTypes(); return true; }
private int addPolygon(int[] polygon, BS bs) { int n = pc; if (pc == 0) pis = AU.newInt2(SEED_COUNT); else if (pc == pis.length) pis = (int[][]) AU.doubleLength(pis); if (bs != null) bs.set(pc); pis[pc++] = polygon; return n; }
private int addPolygon(int[] polygon, BS bs) { int n = polygonCount; if (polygonCount == 0) polygonIndexes = AU.newInt2(SEED_COUNT); else if (polygonCount == polygonIndexes.length) polygonIndexes = (int[][]) AU.doubleLength(polygonIndexes); if (bs != null) bs.set(polygonCount); polygonIndexes[polygonCount++] = polygon; return n; }
public void resetTransPolygons() { boolean isTranslucent = C.isColixTranslucent(colix); float translucentLevel = C.getColixTranslucencyFractional(colix); for (int i = 0; i < pc; i++) if (bsTransPolygons.get(i)) { if (!setABC(i)) continue; vcs[iA] = C.getColixTranslucent3(vcs[iA], isTranslucent, translucentLevel); vcs[iB] = C.getColixTranslucent3(vcs[iB], isTranslucent, translucentLevel); vcs[iC] = C.getColixTranslucent3(vcs[iC], isTranslucent, translucentLevel); } bsTransPolygons = null; polygonTranslucencies = null; }
protected void jvxlDecodeContourData(JvxlData jvxlData, String data) throws Exception { List<List<Object>> vs = new List<List<Object>>(); SB values = new SB(); SB colors = new SB(); int pt = -1; jvxlData.vContours = null; if (data == null) return; while ((pt = data.indexOf("<jvxlContour", pt + 1)) >= 0) { List<Object> v = new List<Object>(); String s = xr.getXmlData("jvxlContour", data.substring(pt), true, false); float value = parseFloatStr(XmlReader.getXmlAttrib(s, "value")); values.append(" ").appendF(value); int color = getColor(XmlReader.getXmlAttrib(s, "color")); short colix = C.getColix(color); colors.append(" ").append(Escape.escapeColor(color)); String fData = JvxlCoder.jvxlDecompressString(XmlReader.getXmlAttrib(s, "data")); BS bs = JvxlCoder.jvxlDecodeBitSet(xr.getXmlData("jvxlContour", s, false, false)); int n = bs.length(); IsosurfaceMesh.setContourVector(v, n, bs, value, colix, color, SB.newS(fData)); vs.addLast(v); } int n = vs.size(); if (n > 0) { jvxlData.vContours = AU.createArrayOfArrayList(n); // 3D contour values and colors jvxlData.contourColixes = params.contourColixes = new short[n]; jvxlData.contourValues = params.contoursDiscrete = new float[n]; for (int i = 0; i < n; i++) { jvxlData.vContours[i] = vs.get(i); jvxlData.contourValues[i] = ((Float) jvxlData.vContours[i].get(2)).floatValue(); jvxlData.contourColixes[i] = ((short[]) jvxlData.vContours[i].get(3))[0]; } jvxlData.contourColors = C.getHexCodes(jvxlData.contourColixes); Logger.info("JVXL read: " + n + " discrete contours"); Logger.info("JVXL read: contour values: " + values); Logger.info("JVXL read: contour colors: " + colors); } }
/** * @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); }
private void renderShapes() { BioShapeCollection mps = (BioShapeCollection) shape; for (int c = mps.bioShapes.length; --c >= 0; ) { BioShape bioShape = mps.getBioShape(c); if ((bioShape.modelVisibilityFlags & myVisibilityFlag) == 0) continue; if (bioShape.monomerCount >= 2 && initializePolymer(bioShape)) { bsRenderMesh.clearAll(); renderBioShape(bioShape); renderMeshes(); freeTempArrays(); } } }
@Override public void processStartElement(String localName) { String[] tokens; // System.out.println( " " + localName + " " + atts); // System.out.println("xmlchem3d: start " + localName); if ("Molecule".equalsIgnoreCase(localName)) { asc.newAtomSet(); asc.setAtomSetName(atts.get("Name")); return; } if ("LinearChain".equalsIgnoreCase(localName)) { iGroup = 0; iChain++; } if ("RepeatUnit".equalsIgnoreCase(localName)) { iGroup++; } if ("Atom3d".equalsIgnoreCase(localName)) { atom = new Atom(); atom.elementSymbol = atts.get("Components"); atom.atomName = atts.get("ID"); atom.atomSerial = ++iAtom; if (iChain >= 0) parent.setChainID(atom, "" + (char) ((iChain - 1) % 26 + 'A')); atom.group3 = "UNK"; if (iGroup == 0) iGroup = 1; atom.sequenceNumber = iGroup; String xyz = atts.get("XYZ"); if (xyz != null) { tokens = getTokensStr(xyz.replace(',', ' ')); atom.set(parseFloatStr(tokens[0]), parseFloatStr(tokens[1]), parseFloatStr(tokens[2])); } boolean isBackbone = "1".equals(atts.get("IsBackboneAtom")); if (isBackbone) bsBackbone.set(iAtom); return; } if ("Bond".equalsIgnoreCase(localName)) { String[] atoms = PT.split(atts.get("Connects"), ","); int order = 1; if (atts.containsKey("Type")) { String type = atts.get("Type"); if (type.equals("Double")) order = 2; else if (type.equals("Triple")) order = 3; } asc.addNewBondFromNames(atoms[0], atoms[1], order); return; } }
private void setVis(Map<?, Ellipsoid> ellipsoids, BS bs, Atom[] atoms) { for (Ellipsoid e : ellipsoids.values()) { Tensor t = e.tensor; boolean isOK = (t != null && e.isValid && e.isOn); if (isOK && t.atomIndex1 >= 0) { if (t.iType == Tensor.TYPE_ADP) { boolean isModTensor = t.isModulated; boolean isUnmodTensor = t.isUnmodulated; boolean isModAtom = ms.isModulated(t.atomIndex1); isOK = (!isModTensor && !isUnmodTensor || isModTensor == isModAtom); } atoms[t.atomIndex1].setShapeVisibility(vf, true); } e.visible = isOK && (e.modelIndex < 0 || bs.get(e.modelIndex)); } }
private static float checkSlab( int tokType, T3 v, float val, float distance, P4 plane, T3[] ptCenters, BS bs) { float d; switch (tokType) { case T.decimal: return (val >= 0 && bs.get((int) val) ? 1 : -1); case T.min: d = distance - val; break; case T.max: d = val - distance; break; case T.plane: d = Measure.distanceToPlane(plane, v); break; case T.distance: d = minDist(v, ptCenters) - distance; break; default: d = -minDist(v, ptCenters) - distance; break; } return (Math.abs(d) < 0.0001f ? 0 : d); }
@Override protected void outputSurface( P3[] vertices, V3[] normals, short[] colixes, int[][] indices, short[] polygonColixes, int nVertices, int nPolygons, int nFaces, BS bsPolygons, int faceVertexMax, short colix, List<Short> colorList, Map<Short, Integer> htColixes, P3 offset) { if (polygonColixes != null) { boolean isAll = (bsPolygons == null); int i0 = (isAll ? nPolygons - 1 : bsPolygons.nextSetBit(0)); for (int i = i0; i >= 0; i = (isAll ? i - 1 : bsPolygons.nextSetBit(i + 1))) { // if ((p++) % 10 == 0) // output("\n"); output("polygon { 4\n"); for (int j = 0; j <= 3; j++) outputVertex(vertices[indices[i][j % 3]], offset); output("\n"); output("pigment{rgbt<" + color4(colix = polygonColixes[i]) + ">}\n"); output(" translucentFinish(" + translucencyFractionalFromColix(colix) + ")\n"); output(" check_shadow()\n"); output(" clip()\n"); output("}\n"); } return; } output("mesh2 {\n"); output("vertex_vectors { " + nVertices); for (int i = 0; i < nVertices; i++) outputVertex(vertices[i], offset); output("\n}\n"); boolean haveNormals = (normals != null); if (haveNormals) { output("normal_vectors { " + nVertices); for (int i = 0; i < nVertices; i++) { setTempVertex(vertices[i], offset, tempP2); output(getScreenNormal(tempP2, normals[i], 1)); output("\n"); } output("\n}\n"); } if (colixes != null) { int nColix = colorList.size(); output("texture_list { " + nColix); // just using the transparency of the first colix there... String finish = ">}" + " translucentFinish(" + translucencyFractionalFromColix(colixes[0]) + ")}"; for (int i = 0; i < nColix; i++) output("\n, texture{pigment{rgbt<" + color4(colorList.get(i).shortValue()) + finish); output("\n}\n"); } output("face_indices { " + nFaces); boolean isAll = (bsPolygons == null); int i0 = (isAll ? nPolygons - 1 : bsPolygons.nextSetBit(0)); for (int i = i0; i >= 0; i = (isAll ? i - 1 : bsPolygons.nextSetBit(i + 1))) { output(", <" + getTriad(indices[i]) + ">"); if (colixes != null) { output("," + htColixes.get(Short.valueOf(colixes[indices[i][0]]))); output("," + htColixes.get(Short.valueOf(colixes[indices[i][1]]))); output("," + htColixes.get(Short.valueOf(colixes[indices[i][2]]))); } if (faceVertexMax == 4 && indices[i].length == 4) { output(", <" + indices[i][0] + "," + indices[i][2] + "," + indices[i][3] + ">"); if (colixes != null) { output("," + htColixes.get(Short.valueOf(colixes[indices[i][0]]))); output("," + htColixes.get(Short.valueOf(colixes[indices[i][2]]))); output("," + htColixes.get(Short.valueOf(colixes[indices[i][3]]))); } } output("\n"); } output("\n}\n"); if (colixes == null) { output("pigment{rgbt<" + color4(colix) + ">}\n"); output(" translucentFinish(" + translucencyFractionalFromColix(colix) + ")\n"); } output(" check_shadow()\n"); output(" clip()\n"); output("}\n"); /* mesh2 { vertex_vectors { 9, <0,0,0>, <0.5,0,0>, <0.5,0.5,0>, <1,0,0>, <1,0.5,0>, <1,1,0> <0.5,1,0>, <0,1,0>, <0,0.5,0> } normal_vectors { 9, <-1,-1,0>, <0,-1,0>, <0,0,1>, <1,-1,0>, <1,0,0>, <1,1,0>, <0,1,0>, <-1,1,0>, <-1,0,0> } texture_list { 3, texture{pigment{rgb <0,0,1>}}, texture{pigment{rgb 1}}, texture{pigment{rgb <1,0,0>}} } face_indices { 8, <0,1,2>,0,1,2, <1,3,2>,1,0,2, <3,4,2>,0,1,2, <4,5,2>,1,0,2, <5,6,2>,0,1,2, <6,7,2>,1,0,2, <7,8,2>,0,1,2, <8,0,2>,1,0,2 } } */ }
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; } }
public boolean slabPolygons(Object[] slabObject, boolean allowCap) { if (polygonCount0 < 0) return false; // disabled for some surface types int slabType = ((Integer) slabObject[0]).intValue(); if (slabType == T.none || slabType == T.brillouin) { if (bsSlabDisplay != null && (polygonCount0 != 0 || vertexCount0 != 0)) { pc = polygonCount0; vc = vertexCount0; polygonCount0 = vertexCount0 = 0; normixCount = (isTriangleSet ? pc : vc); bsSlabDisplay.setBits(0, (pc == 0 ? vc : pc)); slabOptions = new SB().append(meshType + " slab none"); bsSlabGhost = null; slabMeshType = T.none; } if (slabType == T.none) return false; } Object slabbingObject = slabObject[1]; boolean andCap = ((Boolean) slabObject[2]).booleanValue() && !(slabType == T.brillouin); if (andCap && !allowCap) return false; Object[] colorData = (Object[]) slabObject[3]; boolean isGhost = (colorData != null); if (bsSlabDisplay == null || polygonCount0 == 0 && vertexCount0 == 0) { polygonCount0 = pc; vertexCount0 = vc; bsSlabDisplay = BSUtil.setAll(pc == 0 ? vc : pc); bsSlabGhost = null; if (pc == 0 && vc == 0) return false; } else if (isMerged) { if (pc == 0) bsSlabDisplay.setBits(mergeVertexCount0, vc); else bsSlabDisplay.setBits(mergePolygonCount0, pc); } if (isGhost) { if (bsSlabGhost == null) bsSlabGhost = new BS(); slabMeshType = ((Integer) colorData[0]).intValue(); slabColix = ((Short) colorData[1]).shortValue(); // if (C.isColixColorInherited(slabColix)) // slabColix = C.copyColixTranslucency(slabColix, colix); andCap = false; colix = C.getColixTranslucent3(colix, false, 0); } SB sb = new SB(); sb.append(andCap ? " cap " : " slab "); if (isGhost) { sb.append("translucent ").appendF(C.getColixTranslucencyFractional(slabColix)).append(" "); String s = C.getHexCode(slabColix); if (s != null) sb.append(s).append(" "); if (slabMeshType == T.mesh) sb.append("mesh "); } switch (slabType) { case T.brillouin: sb.append("brillouin"); slabBrillouin((P3[]) slabbingObject); break; case T.decimal: getIntersection( 0, null, null, null, null, (BS) slabbingObject, null, andCap, false, T.decimal, isGhost); break; case T.plane: P4 plane = (P4) slabbingObject; sb.append(Escape.eP4(plane)); getIntersection(0, plane, null, null, null, null, null, andCap, false, T.plane, isGhost); break; case T.unitcell: case T.boundbox: P3[] box = (P3[]) slabbingObject; sb.append("within ").append(Escape.eAP(box)); P4[] faces = BoxInfo.getFacesFromCriticalPoints(box); for (int i = 0; i < faces.length; i++) { getIntersection( 0, faces[i], null, null, null, null, null, andCap, false, T.plane, isGhost); } break; case T.data: getIntersection( 0, null, null, null, (float[]) slabbingObject, null, null, false, false, T.min, isGhost); break; case T.within: case T.range: case T.mesh: Object[] o = (Object[]) slabbingObject; float distance = ((Float) o[0]).floatValue(); switch (slabType) { case T.within: P3[] points = (P3[]) o[1]; BS bs = (BS) o[2]; sb.append("within ") .appendF(distance) .append(bs == null ? Escape.e(points) : Escape.e(bs)); getIntersection( distance, null, points, null, null, null, null, andCap, false, (distance > 0 ? T.distance : T.sphere), isGhost); break; case T.range: // isosurface slab within range x.x y.y // if y.y < x.x then this effectively means "NOT within range y.y x.x" if (vvs == null) return false; float distanceMax = ((Float) o[1]).floatValue(); sb.append("within range ").appendF(distance).append(" ").appendF(distanceMax); bs = (distanceMax < distance ? BSUtil.copy(bsSlabDisplay) : null); getIntersection( distance, null, null, null, null, null, null, andCap, false, T.min, isGhost); BS bsA = (bs == null ? null : BSUtil.copy(bsSlabDisplay)); BSUtil.copy2(bs, bsSlabDisplay); getIntersection( distanceMax, null, null, null, null, null, null, andCap, false, T.max, isGhost); if (bsA != null) bsSlabDisplay.or(bsA); break; case T.mesh: // NOT IMPLEMENTED MeshSurface mesh = (MeshSurface) o[1]; // distance = -1; getIntersection( 0, null, null, null, null, null, mesh, andCap, false, distance < 0 ? T.min : T.max, isGhost); // TODO: unresolved how exactly to store this in the state // -- must indicate exact set of triangles to slab and how! break; } break; } String newOptions = sb.toString(); if (slabOptions == null) slabOptions = new SB(); if (slabOptions.indexOf(newOptions) < 0) slabOptions.append(slabOptions.length() > 0 ? "; " : "").append(meshType).append(newOptions); return true; }