001/* 002 * Entity102_CompositeCurve -- Entity that represents a composite curve made up of other curve segments. 003 * 004 * Copyright (C) 2011-2025, Joseph A. Huwaldt. All rights reserved. 005 * 006 * This library is free software; you can redistribute it and/or 007 * modify it under the terms of the GNU Lesser General Public 008 * License as published by the Free Software Foundation; either 009 * version 2.1 of the License, or (at your option) any later version. 010 * 011 * This library is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 * Lesser General Public License for more details. 015 * 016 * You should have received a copy of the GNU Lesser General Public License 017 * along with this program; if not, write to the Free Software 018 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 019 * Or visit: http://www.gnu.org/licenses/lgpl.html 020 * 021 * Based on, but heavily modified from, IGESView ( http://ts.nist.gov/Standards/IGES/igesTools.cfm ) 022 */ 023package geomss.geom.reader.iges; 024 025import geomss.geom.*; 026import geomss.geom.nurbs.CurveUtils; 027import geomss.geom.nurbs.NurbsCurve; 028import jahuwaldt.js.param.Parameter; 029import java.io.IOException; 030import java.io.PrintWriter; 031import java.io.RandomAccessFile; 032import java.util.ArrayList; 033import java.util.List; 034import javax.measure.quantity.Length; 035 036/** 037 * <b><i>COMPOSITE CURVE ENTITY</i></b> - This entity defines an associativity 038 * relationship between an ordered list of curve segments. A composite curve is defined as 039 * an ordered list of entities consisting of a point, connect point and parameterized 040 * curve entities. 041 * 042 * <p> 043 * This entity, when read from an IGES file, is converted to a single NurbsCurve with the 044 * original segments stored in the list "IGES_102_CCSegs" in the user data of the curve. 045 * This entity type can be written out to an IGES file.</p> 046 * 047 * <p> Modified by: Joseph A. Huwaldt </p> 048 * 049 * @author Joseph A. Huwaldt, Date: November 16, 2011 050 * @version February 22, 2025 051 */ 052public class Entity102_CompositeCurve extends GeomSSEntity { 053 054 protected List<Integer> pointers = new ArrayList(); // List of entity DE numbers. 055 056 private NurbsCurve curve = null; // The NURBS curve that will represent the composit curve. 057 058 /** 059 * Default constructor. 060 * 061 * @param p part to which this entity is contained 062 * @param de Directory Entry for this entity 063 */ 064 public Entity102_CompositeCurve(Part p, DirEntry de) { 065 super(p, de); 066 067 if (Constants.DEBUG) { 068 System.out.println("Entity102 constructor called"); 069 } 070 } 071 072 /** 073 * Create this entity from the specified list of pointers to the curve segment DEs. 074 * 075 * @param part The Part to which this entity is contained. 076 * @param DEnum The line count from the start of the Directory Entry Section for 077 * this entry (odd number). 078 * @param name The GeomSS name for this entity or <code>null</code> for none. 079 * @param segDEPtrs A list of pointers to the DE each segment of the curve in order 080 * from start to end. 081 */ 082 public Entity102_CompositeCurve(Part part, int DEnum, String name, List<Integer> segDEPtrs) { 083 super(part, new DirEntry(102, 0, DEnum, 0, name)); 084 085 pointers.addAll(segDEPtrs); 086 } 087 088 /** 089 * Checks to see if the entity is correct. No restrictions are imposed. 090 */ 091 @Override 092 public void check() { } 093 094 /** 095 * Read the Parameter Data from the String read in by the superclass. 096 * 097 * @param in input file 098 * @throws java.io.IOException if the parameter could not be read in. 099 */ 100 @Override 101 public void read(RandomAccessFile in) throws IOException { 102 super.read(in); 103 String s = getPDString(); 104 105 if (Constants.DEBUG) { 106 System.out.println("PD String = \"" + s + "\""); 107 } 108 109 int n = getInt(s); 110 for (int i = 0; i < n; ++i) 111 pointers.add(getInt(s)); 112 113 super.read_additional(); 114 } 115 116 /** 117 * The GeomSS geometry element is created from the IGES parameters when this method is 118 * called. 119 */ 120 @Override 121 void createGeometry() { 122 Part part = getPart(); 123 124 // Loop over all the entities in this association. 125 GeomList<GeomElement> geom = GeomList.newInstance(); 126 int n = pointers.size(); 127 for (int i = 0; i < n; ++i) { 128 int deNum = pointers.get(i); 129 Entity entity = part.getEntity(deNum); 130 131 if (entity instanceof GeomSSEntity) { 132 // Found a GeomSS geometry Entity. 133 GeomSSEntity geomEntity = (GeomSSEntity)entity; 134 geomEntity.setUsedInList(true); // Indicate that the entity is used by this association. 135 GeomElement element = geomEntity.getGeomElement(GTransform.IDENTITY); 136 geom.add(element); 137 } 138 } 139 140 // Convert all the non-degenerate elements into NURBS curves. 141 Parameter<Length> tol = Parameter.valueOf(Constants.Grain, Constants.unit); 142 GeomList<NurbsCurve> crvSegs = convert2NurbsSegs(geom, tol); 143 144 // Concatentate all the curve segments together. 145 curve = CurveUtils.connectCurves(crvSegs); 146 GeomList.recycle(crvSegs); 147 148 // TODO: Remove unnecessary knots to return the minimal curve that matches the original. 149 curve.putUserData("IGES_102_CCSegs", geom); 150 151 } 152 153 /** 154 * Converts all the non-degenerate Curve elements in the specified geometry list into 155 * NurbsCurves. 156 * 157 * @param crvs The list of geometry elements to be converted. 158 * @param tol The tolerance for the conversion to NURBS curves. 159 * @return A list of non-degenerate NURBS curve versions of each element in "crvs". 160 */ 161 private GeomList<NurbsCurve> convert2NurbsSegs(GeomList<GeomElement> crvs, Parameter<Length> tol) { 162 GeomList<NurbsCurve> nurbsSegs = GeomList.newInstance(); 163 for (GeomElement elem : crvs) { 164 if (elem instanceof Curve) { 165 NurbsCurve nurbs = ((Curve)elem).toNurbs(tol); 166 if (!nurbs.isDegenerate(tol)) 167 nurbsSegs.add(nurbs); 168 } 169 } 170 return nurbsSegs; 171 } 172 173 /** 174 * Return a reference to the Transformable GeomElement contained in this IGES Entity. 175 * 176 * @return A reference to the Transformable GeomElement contained in this IGES Entity. 177 */ 178 @Override 179 protected Transformable getGeomElement() { 180 return curve; 181 } 182 183 /** 184 * Returns <code>true</code> if the Entity can be written to an exchange file. 185 * 186 * @return true 187 */ 188 @Override 189 public boolean canWrite() { 190 return true; 191 } 192 193 /** 194 * Write this entity object's parameter data to the specified PrintWriter. 195 * 196 * @param writer The PrintWriter to write the parameter data for this entity to. 197 * @param PDnum The starting Parameter Data row index number. 198 * @return The Parameter Data row index number for the next row. 199 * @throws java.io.IOException if the parameter data could not be written. 200 */ 201 @Override 202 public int write(PrintWriter writer, int PDnum) throws IOException { 203 int numSegs = pointers.size(); 204 205 // Build up the parameter data string. 206 StringBuilder buffer = new StringBuilder(); 207 buffer.append(102); buffer.append(Constants.Delim); 208 buffer.append(numSegs); buffer.append(Constants.Delim); 209 buffer.append(pointers.get(0)); 210 for (int i = 1; i < numSegs; ++i) { 211 buffer.append(Constants.Delim); 212 buffer.append(pointers.get(i)); 213 } 214 buffer.append(Constants.Term); 215 216 // Write it out. 217 int oldPDnum = PDnum; 218 PDnum = Constants.writeSection(writer, PDnum, Constants.makeSequenceNumber(getDENum()), 219 'P', buffer); 220 221 // Store the PD line number and line count in the directory entry. 222 getDirectoryEntry().setPDNumber(oldPDnum, PDnum - oldPDnum); 223 224 return PDnum; 225 } 226 227 /** 228 * Dump to String. 229 * 230 * @return String containing the resulting text. 231 */ 232 @Override 233 public String toString() { 234 StringBuilder outStr = new StringBuilder(super.toString()); 235 outStr.append("\n"); 236 237 int n = pointers.size(); 238 outStr.append("n = "); outStr.append(n); outStr.append("\n"); 239 240 for (int i = 0; i < n; i++) { 241 outStr.append("curve("); 242 outStr.append(i); 243 outStr.append(") = "); 244 outStr.append(pointers.get(i)); 245 outStr.append("\n"); 246 } 247 248 return outStr.toString(); 249 } 250 251 /** 252 * Returns a short String describing this Entity object's type. 253 * 254 * @return A short String describing this Entity object's type. 255 */ 256 @Override 257 public String getTypeString() { 258 return "Entity102 - Composite Curve"; 259 } 260 261}