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