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 // =======================================================================
26 // function : RWMesh_MaterialMap
28 // =======================================================================
29 RWMesh_MaterialMap::RWMesh_MaterialMap (const TCollection_AsciiString& theFile)
30 : myFileName (theFile),
36 TCollection_AsciiString aFileName, aFileExt;
37 OSD_Path::FolderAndFileFromPath (theFile, myFolder, aFileName);
38 OSD_Path::FileNameAndExtension (aFileName, myShortFileNameBase, aFileExt);
41 // =======================================================================
42 // function : ~RWMesh_MaterialMap
44 // =======================================================================
45 RWMesh_MaterialMap::~RWMesh_MaterialMap()
50 // =======================================================================
51 // function : AddMaterial
53 // =======================================================================
54 TCollection_AsciiString RWMesh_MaterialMap::AddMaterial (const XCAFPrs_Style& theStyle)
56 if (myStyles.IsBound1 (theStyle))
58 return myStyles.Find1 (theStyle);
61 TCollection_AsciiString aMatKey, aMatName, aMatNameSuffix;
63 int* aCounterPtr = &myNbMaterials;
66 if (!theStyle.Material().IsNull()
67 && !theStyle.Material()->IsEmpty())
69 aCounterPtr = &aCounter;
70 Handle(TDataStd_Name) aNodeName;
71 if (!theStyle.Material()->Label().IsNull()
72 && theStyle.Material()->Label().FindAttribute (TDataStd_Name::GetID(), aNodeName))
74 aMatName = aNodeName->Get();
80 aMatNameSuffix = aMatName;
85 aMatNameSuffix = myKeyPrefix;
86 aMatName = aMatNameSuffix + myNbMaterials;
92 aMatKey = myNbMaterials++; // starts from 0
93 aMatNameSuffix = myKeyPrefix;
94 aMatName = aMatNameSuffix + aMatKey;
97 for (;; ++(*aCounterPtr))
99 if (myStyles.IsBound2 (aMatKey))
103 aMatName = aMatNameSuffix + (*aCounterPtr);
108 aMatKey = *aCounterPtr;
109 aMatName = aMatNameSuffix + aMatKey;
116 myStyles.Bind (theStyle, aMatKey);
117 DefineMaterial (theStyle, aMatKey, aMatName);
121 // =======================================================================
122 // function : copyFileTo
124 // =======================================================================
125 bool RWMesh_MaterialMap::copyFileTo (const TCollection_AsciiString& theFileSrc,
126 const TCollection_AsciiString& theFileDst)
128 if (theFileSrc.IsEmpty()
129 || theFileDst.IsEmpty())
133 else if (theFileSrc == theFileDst)
140 OSD_Path aSrcPath (theFileSrc);
141 OSD_Path aDstPath (theFileDst);
142 OSD_File aFileSrc (aSrcPath);
143 if (!aFileSrc.Exists())
145 Message::DefaultMessenger()->Send (TCollection_AsciiString("Failed to copy file - source file '")
146 + theFileSrc + "' does not exist\n", Message_Fail);
149 aFileSrc.Copy (aDstPath);
150 return !aFileSrc.Failed();
152 catch (Standard_Failure const& theException)
154 Message::DefaultMessenger()->Send (TCollection_AsciiString("Failed to copy file\n") +
155 theException.GetMessageString(), Message_Fail);
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())
174 TCollection_AsciiString aSrcTexFolder;
175 OSD_Path::FolderAndFileFromPath (aTextureSrc, aSrcTexFolder, aTexFileName);
176 const TCollection_AsciiString aResTexFile = myTexFolder + aTexFileName;
177 theResTexture = myTexFolderShort + aTexFileName;
178 return copyFileTo (aTextureSrc, aResTexFile);
181 TCollection_AsciiString anExt = theTexture->ProbeImageFileFormat();
186 aTexFileName = theKey + "." + anExt;
188 const TCollection_AsciiString aResTexFile = myTexFolder + aTexFileName;
189 theResTexture = myTexFolderShort + aTexFileName;
190 return theTexture->WriteImage (aResTexFile);
193 // =======================================================================
194 // function : CreateTextureFolder
196 // =======================================================================
197 bool RWMesh_MaterialMap::CreateTextureFolder()
199 if (!myTexFolder.IsEmpty())
204 myTexFolderShort = myShortFileNameBase + "_textures/";
205 myTexFolder = myFolder + "/" + myTexFolderShort;
206 OSD_Path aTexFolderPath (myTexFolder);
207 OSD_Directory aTexDir (aTexFolderPath);
208 if (aTexDir.Exists())
213 OSD_Path aResFolderPath (myFolder);
214 OSD_Directory aResDir (aResFolderPath);
215 if (!aResDir.Exists())
219 const OSD_Protection aParentProt = aResDir.Protection();
220 OSD_Protection aProt = aParentProt;
221 if (aProt.User() == OSD_None)
223 aProt.SetUser (OSD_RWXD);
225 if (aProt.System() == OSD_None)
227 aProt.SetSystem (OSD_RWXD);
230 aTexDir.Build (aProt);
231 if (aTexDir.Failed())
233 // fallback to the same folder as output model file
234 myTexFolder = myFolder;
235 myTexFolderShort.Clear();