1 // Copyright (c) 2017-2019 OPEN CASCADE SAS
3 // This file is part of Open CASCADE Technology software library.
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
14 #include <RWMesh_MaterialMap.hxx>
16 #include <Message.hxx>
17 #include <Message_Messenger.hxx>
18 #include <OSD_Directory.hxx>
19 #include <OSD_File.hxx>
20 #include <OSD_Path.hxx>
21 #include <OSD_Protection.hxx>
22 #include <TDataStd_Name.hxx>
23 #include <TDF_Label.hxx>
25 IMPLEMENT_STANDARD_RTTIEXT(RWMesh_MaterialMap, Standard_Transient)
27 // =======================================================================
28 // function : RWMesh_MaterialMap
30 // =======================================================================
31 RWMesh_MaterialMap::RWMesh_MaterialMap (const TCollection_AsciiString& theFile)
32 : myFileName (theFile),
38 TCollection_AsciiString aFileName, aFileExt;
39 OSD_Path::FolderAndFileFromPath (theFile, myFolder, aFileName);
40 OSD_Path::FileNameAndExtension (aFileName, myShortFileNameBase, aFileExt);
43 // =======================================================================
44 // function : ~RWMesh_MaterialMap
46 // =======================================================================
47 RWMesh_MaterialMap::~RWMesh_MaterialMap()
52 // =======================================================================
53 // function : AddMaterial
55 // =======================================================================
56 TCollection_AsciiString RWMesh_MaterialMap::AddMaterial (const XCAFPrs_Style& theStyle)
58 if (myStyles.IsBound1 (theStyle))
60 return myStyles.Find1 (theStyle);
63 TCollection_AsciiString aMatKey, aMatName, aMatNameSuffix;
65 int* aCounterPtr = &myNbMaterials;
68 if (!theStyle.Material().IsNull()
69 && !theStyle.Material()->IsEmpty())
71 aCounterPtr = &aCounter;
72 Handle(TDataStd_Name) aNodeName;
73 if (!theStyle.Material()->Label().IsNull()
74 && theStyle.Material()->Label().FindAttribute (TDataStd_Name::GetID(), aNodeName))
76 aMatName = aNodeName->Get();
82 aMatNameSuffix = aMatName;
87 aMatNameSuffix = myKeyPrefix;
88 aMatName = aMatNameSuffix + myNbMaterials;
94 aMatKey = myNbMaterials++; // starts from 0
95 aMatNameSuffix = myKeyPrefix;
96 aMatName = aMatNameSuffix + aMatKey;
99 for (;; ++(*aCounterPtr))
101 if (myStyles.IsBound2 (aMatKey))
105 aMatName = aMatNameSuffix + (*aCounterPtr);
110 aMatKey = *aCounterPtr;
111 aMatName = aMatNameSuffix + aMatKey;
118 myStyles.Bind (theStyle, aMatKey);
119 DefineMaterial (theStyle, aMatKey, aMatName);
123 // =======================================================================
124 // function : copyFileTo
126 // =======================================================================
127 bool RWMesh_MaterialMap::copyFileTo (const TCollection_AsciiString& theFileSrc,
128 const TCollection_AsciiString& theFileDst)
130 if (theFileSrc.IsEmpty()
131 || theFileDst.IsEmpty())
135 else if (theFileSrc == theFileDst)
142 OSD_Path aSrcPath (theFileSrc);
143 OSD_Path aDstPath (theFileDst);
144 OSD_File aFileSrc (aSrcPath);
145 if (!aFileSrc.Exists())
147 Message::SendFail (TCollection_AsciiString("Failed to copy file - source file '") + theFileSrc + "' does not exist");
150 aFileSrc.Copy (aDstPath);
151 return !aFileSrc.Failed();
153 catch (Standard_Failure const& theException)
155 Message::SendFail (TCollection_AsciiString("Failed to copy file\n") + theException.GetMessageString());
160 // =======================================================================
161 // function : CopyTexture
163 // =======================================================================
164 bool RWMesh_MaterialMap::CopyTexture (TCollection_AsciiString& theResTexture,
165 const Handle(Image_Texture)& theTexture,
166 const TCollection_AsciiString& theKey)
168 CreateTextureFolder();
170 TCollection_AsciiString aTexFileName;
171 TCollection_AsciiString aTextureSrc = theTexture->FilePath();
172 if (!aTextureSrc.IsEmpty()
173 && theTexture->FileOffset() <= 0
174 && theTexture->FileLength() <= 0)
176 TCollection_AsciiString aSrcTexFolder;
177 OSD_Path::FolderAndFileFromPath (aTextureSrc, aSrcTexFolder, aTexFileName);
178 const TCollection_AsciiString aResTexFile = myTexFolder + aTexFileName;
179 theResTexture = myTexFolderShort + aTexFileName;
180 return copyFileTo (aTextureSrc, aResTexFile);
183 TCollection_AsciiString anExt = theTexture->ProbeImageFileFormat();
188 aTexFileName = theKey + "." + anExt;
190 const TCollection_AsciiString aResTexFile = myTexFolder + aTexFileName;
191 theResTexture = myTexFolderShort + aTexFileName;
192 return theTexture->WriteImage (aResTexFile);
195 // =======================================================================
196 // function : CreateTextureFolder
198 // =======================================================================
199 bool RWMesh_MaterialMap::CreateTextureFolder()
201 if (!myTexFolder.IsEmpty())
206 myTexFolderShort = myShortFileNameBase + "_textures/";
207 myTexFolder = myFolder + "/" + myTexFolderShort;
208 OSD_Path aTexFolderPath (myTexFolder);
209 OSD_Directory aTexDir (aTexFolderPath);
210 if (aTexDir.Exists())
215 OSD_Path aResFolderPath (myFolder);
216 OSD_Directory aResDir (aResFolderPath);
217 if (!aResDir.Exists())
221 const OSD_Protection aParentProt = aResDir.Protection();
222 OSD_Protection aProt = aParentProt;
223 if (aProt.User() == OSD_None)
225 aProt.SetUser (OSD_RWXD);
227 if (aProt.System() == OSD_None)
229 aProt.SetSystem (OSD_RWXD);
232 aTexDir.Build (aProt);
233 if (aTexDir.Failed())
235 // fallback to the same folder as output model file
236 myTexFolder = myFolder;
237 myTexFolderShort.Clear();