File indexing completed on 2025-01-18 10:04:43
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef _RWObj_Reader_HeaderFile
0016 #define _RWObj_Reader_HeaderFile
0017
0018 #include <Message.hxx>
0019 #include <Message_Messenger.hxx>
0020 #include <Message_ProgressRange.hxx>
0021 #include <NCollection_Array1.hxx>
0022 #include <NCollection_DataMap.hxx>
0023 #include <NCollection_IndexedMap.hxx>
0024 #include <NCollection_Vector.hxx>
0025 #include <NCollection_Shared.hxx>
0026 #include <OSD_OpenFile.hxx>
0027 #include <RWMesh_CoordinateSystemConverter.hxx>
0028 #include <RWObj_Material.hxx>
0029 #include <RWObj_SubMesh.hxx>
0030 #include <RWObj_SubMeshReason.hxx>
0031 #include <RWObj_Tools.hxx>
0032 #include <Standard_HashUtils.hxx>
0033
0034 #include <vector>
0035
0036
0037
0038
0039
0040
0041
0042
0043 class RWObj_Reader : public Standard_Transient
0044 {
0045 DEFINE_STANDARD_RTTIEXT(RWObj_Reader, Standard_Transient)
0046 public:
0047
0048
0049 Standard_EXPORT RWObj_Reader();
0050
0051
0052
0053 Standard_Boolean Read (const TCollection_AsciiString& theFile,
0054 const Message_ProgressRange& theProgress)
0055 {
0056 std::ifstream aStream;
0057 OSD_OpenStream(aStream, theFile, std::ios_base::in | std::ios_base::binary);
0058 return Read(aStream, theFile, theProgress);
0059 }
0060
0061
0062
0063
0064 Standard_Boolean Read (std::istream& theStream,
0065 const TCollection_AsciiString& theFile,
0066 const Message_ProgressRange& theProgress)
0067 {
0068 return read(theStream, theFile, theProgress, Standard_False);
0069 }
0070
0071
0072
0073
0074
0075
0076 Standard_Boolean Probe (const TCollection_AsciiString& theFile,
0077 const Message_ProgressRange& theProgress)
0078 {
0079 std::ifstream aStream;
0080 OSD_OpenStream(aStream, theFile, std::ios_base::in | std::ios_base::binary);
0081 return Probe(aStream, theFile, theProgress);
0082 }
0083
0084
0085
0086
0087
0088
0089
0090
0091 Standard_Boolean Probe (std::istream& theStream,
0092 const TCollection_AsciiString& theFile,
0093 const Message_ProgressRange& theProgress)
0094 {
0095 return read(theStream, theFile, theProgress, Standard_True);
0096 }
0097
0098
0099 const TCollection_AsciiString& FileComments() const { return myFileComments; }
0100
0101
0102 const NCollection_IndexedMap<TCollection_AsciiString>& ExternalFiles() const { return myExternalFiles; }
0103
0104
0105 Standard_Integer NbProbeNodes() const { return myNbProbeNodes; }
0106
0107
0108 Standard_Integer NbProbeElems() const { return myNbProbeElems; }
0109
0110
0111 Standard_Size MemoryLimit() const { return myMemLimitBytes; }
0112
0113
0114
0115 void SetMemoryLimit (Standard_Size theMemLimit) { myMemLimitBytes = theMemLimit; }
0116
0117
0118 const RWMesh_CoordinateSystemConverter& Transformation() const { return myCSTrsf; }
0119
0120
0121
0122
0123 void SetTransformation (const RWMesh_CoordinateSystemConverter& theCSConverter) { myCSTrsf = theCSConverter; }
0124
0125
0126 Standard_Boolean IsSinglePrecision() const { return myObjVerts.IsSinglePrecision(); }
0127
0128
0129 void SetSinglePrecision (Standard_Boolean theIsSinglePrecision) { myObjVerts.SetSinglePrecision (theIsSinglePrecision); }
0130
0131 protected:
0132
0133
0134
0135
0136 Standard_EXPORT Standard_Boolean read (std::istream& theStream,
0137 const TCollection_AsciiString& theFile,
0138 const Message_ProgressRange& theProgress,
0139 const Standard_Boolean theToProbe);
0140
0141
0142 protected:
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153 virtual Standard_Boolean addMesh (const RWObj_SubMesh& theMesh,
0154 const RWObj_SubMeshReason theReason) = 0;
0155
0156
0157 virtual gp_Pnt getNode (Standard_Integer theIndex) const = 0;
0158
0159
0160
0161 virtual Standard_Integer addNode (const gp_Pnt& thePnt) = 0;
0162
0163
0164
0165
0166
0167 virtual void setNodeNormal (const Standard_Integer theIndex,
0168 const Graphic3d_Vec3& theNorm) = 0;
0169
0170
0171
0172
0173
0174 virtual void setNodeUV (const Standard_Integer theIndex,
0175 const Graphic3d_Vec2& theUV) = 0;
0176
0177
0178
0179 virtual void addElement (Standard_Integer theN1,
0180 Standard_Integer theN2,
0181 Standard_Integer theN3,
0182 Standard_Integer theN4) = 0;
0183
0184
0185 private:
0186
0187
0188 void pushVertex (const char* theXYZ)
0189 {
0190 char* aNext = NULL;
0191 gp_Pnt anXYZ;
0192 RWObj_Tools::ReadVec3 (theXYZ, aNext, anXYZ.ChangeCoord());
0193 myCSTrsf.TransformPosition (anXYZ.ChangeCoord());
0194
0195 myMemEstim += myObjVerts.IsSinglePrecision() ? sizeof(Graphic3d_Vec3) : sizeof(gp_Pnt);
0196 myObjVerts.Append (anXYZ);
0197 }
0198
0199
0200 void pushNormal (const char* theXYZ)
0201 {
0202 char* aNext = NULL;
0203 Graphic3d_Vec3 aNorm;
0204 RWObj_Tools::ReadVec3 (theXYZ, aNext, aNorm);
0205 myCSTrsf.TransformNormal (aNorm);
0206
0207 myMemEstim += sizeof(Graphic3d_Vec3);
0208 myObjNorms.Append (aNorm);
0209 }
0210
0211
0212 void pushTexel (const char* theUV)
0213 {
0214 char* aNext = NULL;
0215 Graphic3d_Vec2 anUV;
0216 anUV.x() = (float )Strtod (theUV, &aNext);
0217 theUV = aNext;
0218 anUV.y() = (float )Strtod (theUV, &aNext);
0219
0220 myMemEstim += sizeof(Graphic3d_Vec2);
0221 myObjVertsUV.Append (anUV);
0222 }
0223
0224
0225 void pushIndices (const char* thePos);
0226
0227
0228
0229
0230 gp_XYZ polygonCenter (const NCollection_Array1<Standard_Integer>& theIndices);
0231
0232
0233
0234
0235
0236 gp_XYZ polygonNormal (const NCollection_Array1<Standard_Integer>& theIndices);
0237
0238
0239
0240
0241 Standard_Integer triangulatePolygonFan (const NCollection_Array1<Standard_Integer>& theIndices);
0242
0243
0244
0245
0246 Standard_Integer triangulatePolygon (const NCollection_Array1<Standard_Integer>& theIndices);
0247
0248
0249 void pushObject (const char* theObjectName);
0250
0251
0252 void pushGroup (const char* theGroupName);
0253
0254
0255 void pushSmoothGroup (const char* theSmoothGroupIndex);
0256
0257
0258 void pushMaterial (const char* theMaterialName);
0259
0260
0261 void readMaterialLib (const char* theFileName);
0262
0263
0264
0265 bool checkMemory();
0266
0267 protected:
0268
0269
0270 struct ObjVec3iHasher
0271 {
0272 std::size_t operator()(const Graphic3d_Vec3i& theKey) const noexcept
0273 {
0274 return opencascade::hashBytes(&theKey[0], 3 * sizeof(int));
0275 }
0276
0277 bool operator()(const Graphic3d_Vec3i& theKey1,
0278 const Graphic3d_Vec3i& theKey2) const noexcept
0279 {
0280 return theKey1[0] == theKey2[0]
0281 && theKey1[1] == theKey2[1]
0282 && theKey1[2] == theKey2[2];
0283 }
0284 };
0285
0286
0287 class VectorOfVertices
0288 {
0289 public:
0290
0291 VectorOfVertices() : myIsSinglePrecision (Standard_False) {}
0292
0293
0294 bool IsSinglePrecision() const { return myIsSinglePrecision; }
0295
0296
0297 void SetSinglePrecision (Standard_Boolean theIsSinglePrecision)
0298 {
0299 myIsSinglePrecision = theIsSinglePrecision;
0300 myPntVec.Nullify();
0301 myVec3Vec.Nullify();
0302 }
0303
0304
0305 void Reset()
0306 {
0307 if (myIsSinglePrecision)
0308 {
0309 myVec3Vec = new NCollection_Shared<NCollection_Vector<Graphic3d_Vec3> >();
0310 }
0311 else
0312 {
0313 myPntVec = new NCollection_Shared<NCollection_Vector<gp_Pnt> >();
0314 }
0315 }
0316
0317
0318 Standard_Integer Lower() const { return 0; }
0319
0320
0321 Standard_Integer Upper() const { return myIsSinglePrecision ? myVec3Vec->Upper() : myPntVec->Upper(); }
0322
0323
0324 gp_Pnt Value (Standard_Integer theIndex) const
0325 {
0326 if (myIsSinglePrecision)
0327 {
0328 const Graphic3d_Vec3& aPnt = myVec3Vec->Value (theIndex);
0329 return gp_Pnt (aPnt.x(), aPnt.y(), aPnt.z());
0330 }
0331 else
0332 {
0333 return myPntVec->Value (theIndex);
0334 }
0335 }
0336
0337
0338 void Append (const gp_Pnt& thePnt)
0339 {
0340 if (myIsSinglePrecision)
0341 {
0342 myVec3Vec->Append (Graphic3d_Vec3 ((float )thePnt.X(), (float )thePnt.Y(), (float )thePnt.Z()));
0343 }
0344 else
0345 {
0346 myPntVec->Append (thePnt);
0347 }
0348 }
0349 private:
0350 Handle(NCollection_Shared<NCollection_Vector<gp_Pnt> >) myPntVec;
0351 Handle(NCollection_Shared<NCollection_Vector<Graphic3d_Vec3> >) myVec3Vec;
0352 Standard_Boolean myIsSinglePrecision;
0353 };
0354
0355 protected:
0356
0357 NCollection_IndexedMap<TCollection_AsciiString>
0358 myExternalFiles;
0359 TCollection_AsciiString myFileComments;
0360 TCollection_AsciiString myFolder;
0361 RWMesh_CoordinateSystemConverter myCSTrsf;
0362 Standard_Size myMemLimitBytes;
0363 Standard_Size myMemEstim;
0364 Standard_Integer myNbLines;
0365 Standard_Integer myNbProbeNodes;
0366 Standard_Integer myNbProbeElems;
0367 Standard_Integer myNbElemsBig;
0368 Standard_Boolean myToAbort;
0369
0370
0371
0372
0373
0374
0375 VectorOfVertices myObjVerts;
0376 NCollection_Vector<Graphic3d_Vec2> myObjVertsUV;
0377 NCollection_Vector<Graphic3d_Vec3> myObjNorms;
0378 NCollection_DataMap<Graphic3d_Vec3i, Standard_Integer, ObjVec3iHasher>
0379 myPackedIndices;
0380 NCollection_DataMap<TCollection_AsciiString, RWObj_Material>
0381 myMaterials;
0382
0383 RWObj_SubMesh myActiveSubMesh;
0384 std::vector<Standard_Integer> myCurrElem;
0385 };
0386
0387 #endif