From 73174b7081625efe6020ea0e7a2d7809ee0331c5 Mon Sep 17 00:00:00 2001 From: Wil Shipley Date: Thu, 12 Mar 2015 20:23:21 -0700 Subject: [PATCH 01/51] Hard-coded project to build static library for iOS / OS X - This may not appeal to everyone, but I wanted a simple static library Project I could include in a Xcode Workspace that would auto-build when I built an iOS or OS X app. - If you drag this project file into your Workspace and then add the libassimp.x.x.a file as a dependency in your project inspector, it should auto-build in the architecture of your choice. --- .../xcode6/Assimp.xcodeproj/project.pbxproj | 1808 +++++++++++++++++ 1 file changed, 1808 insertions(+) create mode 100644 workspaces/xcode6/Assimp.xcodeproj/project.pbxproj diff --git a/workspaces/xcode6/Assimp.xcodeproj/project.pbxproj b/workspaces/xcode6/Assimp.xcodeproj/project.pbxproj new file mode 100644 index 000000000..5efc9edfa --- /dev/null +++ b/workspaces/xcode6/Assimp.xcodeproj/project.pbxproj @@ -0,0 +1,1808 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 02D9D7977CF34425A1E4D0C1 /* OptimizeGraph.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AAB9AE5328F843F5A8A3E85C /* OptimizeGraph.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 02FE70F552DA42B0AF5BA35E /* ImporterRegistry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D029CE902F8045B0B3AFFDDB /* ImporterRegistry.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 0C43D2C2124D45AFB210AD77 /* JoinVerticesProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B36DA471B9E142FC9425EC45 /* JoinVerticesProcess.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 0C68C4CF4C724B28888ABF43 /* ACLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F1076BAC69DB4935A93045A8 /* ACLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 0D2216F34ABC46919011B229 /* HMPLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43ABFF591F374920A5E18A24 /* HMPLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 11DA6BD79AB44123958A3748 /* SplitLargeMeshes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A43641DC9C1B4B578BC40476 /* SplitLargeMeshes.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 12781B32512D411BA3FBD224 /* PostStepRegistry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E663847651834244834CB9F5 /* PostStepRegistry.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 12DFE025ED3E4527BA61D494 /* MaterialSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7FF72CB6E99E40E19AE0E64C /* MaterialSystem.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 13237D91501F46EB8EC4F25C /* AssbinExporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6389F68312384CFD847B1D13 /* AssbinExporter.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 13F5EF2AA13741BEAA52744A /* LWOAnimation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 680C392FFE0B4CC5ABC7CA64 /* LWOAnimation.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 155A517D4D8040069E88337F /* UnrealLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3B8FD96D46314ACD8F157AC3 /* UnrealLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 19F3FA59D54E434586302A8E /* irrXML.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 64C6BACDA5DD4139AA26EE81 /* irrXML.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 1AD243EFA96047218513620C /* ProcessHelper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 890E32C714444692AA016AE5 /* ProcessHelper.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 1C4683268E00454284E8C1D2 /* IFCUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 59E3D32E3FC7438DB148537F /* IFCUtil.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 1CB938B3E5994902BABC1F2B /* OFFLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EFD557FE2C3A46D78F070655 /* OFFLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 1EBC60AC385E4D28B639B182 /* FBXConverter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7A56A688A3845768410F500 /* FBXConverter.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 1F903C0A02D34828AD87609E /* XFileImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 06DB494DCE4D47FDA00E8B35 /* XFileImporter.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 1FA6FB6673934D11BFD23F41 /* FBXDocument.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F22D5BA425444A028DA42BEA /* FBXDocument.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 212780A32DA8413D976187AB /* BaseImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A58410FEAA884A2D8D73ACCE /* BaseImporter.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 227AF9BA6440437DBD69ABAB /* FindDegenerates.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BABB7734139C452A9DDEE797 /* FindDegenerates.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 231DEB2636A245B6A123B373 /* B3DImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB4BB481FB461688FE2F29 /* B3DImporter.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 24850C77B93042A5BF680D60 /* MD5Parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0BC5FD00572F4C58B267A0EC /* MD5Parser.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 249B88B0A31A47CA90934CA9 /* Exporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FF4E90FB1A3446F095ECC8BD /* Exporter.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 251969D55FFA442180D0AF58 /* MD3Loader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 563FBACCFD774BDEA4AEAC10 /* MD3Loader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 25EBF16E84324F5C89A7F3FB /* RawLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1D4A669762194B9D9A26DD20 /* RawLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 2A010C4331924629B44D800C /* XFileExporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 435DC362E63D4CCBA68656D3 /* XFileExporter.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 2A320C69D24C45C3A9D9C14E /* MDLLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AA92FFC8B06D4569AD9C4CB1 /* MDLLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 2CA0229CCE5C4D0BB44176AB /* ioapi.c in Sources */ = {isa = PBXBuildFile; fileRef = AF75E6049338489BB256D295 /* ioapi.c */; settings = {COMPILER_FLAGS = ""; }; }; + 3091FA821E084C7EAC5C353E /* LWOMaterial.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ED21FC57A384CE6B4F53C0C /* LWOMaterial.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 3331B1D6A54A4BFE9A595B4E /* ASEParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 929F59CCA32549EC884A5033 /* ASEParser.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 34B01510829644E0B2B8A196 /* IFCLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0E9BB0220704C5D93CE7CE9 /* IFCLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 366C5700997F4FE3AE12CCF4 /* TextureTransform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF76D04D95E649BCBC15E64F /* TextureTransform.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 3A0E96946CD74F4B856517D2 /* OgreStructs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 79A49EFE23E34E1CBA2E4377 /* OgreStructs.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 3A518149B13B4C88BEEA4650 /* OptimizeMeshes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACC87E846AE4E4A86E1AEF4 /* OptimizeMeshes.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 3CC1408ACD3249ECA00408B7 /* FBXBinaryTokenizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1108AC28566B4D2B9F27C691 /* FBXBinaryTokenizer.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 3DC78BDA28EA4022BB1F13FD /* Assimp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 705D30EE141A48F292783F0E /* Assimp.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 3ED4918301614730B510E884 /* DeboneProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6E20FCC571F144DDBD831CCB /* DeboneProcess.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 3F8B686D2E214E2F8C93B12D /* NFFLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0D6E8E292F594A2DAFF53564 /* NFFLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 405D15DF00D3447ABC2C78E5 /* Bitmap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 10238FBD7A9D401A82D667CB /* Bitmap.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 414FE97260614C37AE76CCE0 /* XFileParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 74C02A113B804568A7E39CBC /* XFileParser.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 4429D10DE70A415483DACEAF /* BaseProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAB6BC13FCFE40F5801D0972 /* BaseProcess.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 44C9833378BF4F0A8D803022 /* TargetAnimation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6F65B6129F774AEDB8DC845A /* TargetAnimation.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 498D9244682B4746864377DA /* 3DSConverter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15221A74FC9C4B2AAA7306E3 /* 3DSConverter.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 4A42D471540842B1933F1D84 /* OgreXmlSerializer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EF9F805A4BA4428CA98C9DE5 /* OgreXmlSerializer.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 4B0EEEEFEB4E434789BB249D /* CalcTangentsProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90DD6CA40A5E41458E11FF3E /* CalcTangentsProcess.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 4CC8B99EBE8C4CDF83AE4B25 /* BlenderModifier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3106D75C13874F5AB3EBBFE7 /* BlenderModifier.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 4D1710ECAFB640A99F15D406 /* ColladaExporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1C0527629078403F81CFD117 /* ColladaExporter.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 4DDD54E33C674EE89A85AE97 /* BlenderScene.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE0D259917354C80BE1CC791 /* BlenderScene.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 4F3A69E237A1457EA41FBFF2 /* MD5Loader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A277DBC1EFB944F995659A20 /* MD5Loader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 53E7CEA593864ECCBA27EB37 /* IFCGeometry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3267EBBA6EEB435F83FF25E4 /* IFCGeometry.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 557F2B5892074E42A7774D8F /* TerragenLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4866DA5A7BFD49F79B61CBF8 /* TerragenLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 55E02364DDC84751854342DA /* NDOLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B4F1B5789CA540C78FB9219D /* NDOLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 5604BB8263B043F9B3778D0D /* SMDLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FD9BEC6B8A264AB092F98E20 /* SMDLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 56D8494BFA2447EF9DAF0E8B /* IRRLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97DFA90F9D0C4B999C150B10 /* IRRLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 5861B04C98FF4BF2A1D90C43 /* MakeVerboseFormat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 21B797DAB0E0427C9339AE0F /* MakeVerboseFormat.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 5934E68DD8744098B694D8C9 /* VertexTriangleAdjacency.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0AAF26EBF0A64ABDB840BA64 /* VertexTriangleAdjacency.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 5CBC282D206847F791F2ADAF /* DXFLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 466D6B9A7CCD402D9AA87071 /* DXFLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 5CD0466AD8454EF88928D43F /* FBXMeshGeometry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42E110B9E6924AF9B55AE65A /* FBXMeshGeometry.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 61B4DFF611244C35845961C0 /* DefaultIOSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1D502654EF864101A2DA9476 /* DefaultIOSystem.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 64493DD9B731476BBB5F9BA6 /* ComputeUVMappingProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ABBB4561E72413EB40702C3 /* ComputeUVMappingProcess.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 6955346149D346A0AEE7AA13 /* sweep_context.cc in Sources */ = {isa = PBXBuildFile; fileRef = 5E10483FBE6D4F4594B460E0 /* sweep_context.cc */; settings = {COMPILER_FLAGS = ""; }; }; + 6ABAC74C1F9A406A921A7662 /* ObjExporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE811A81663A492A84E13937 /* ObjExporter.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 6B1CE2A7564543E79A391FA1 /* RemoveRedundantMaterials.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ADACEBC4973F4FC0A6FEC68A /* RemoveRedundantMaterials.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 6B5223FAAD874885A6B3ED5C /* unzip.c in Sources */ = {isa = PBXBuildFile; fileRef = 973D4231A4AA4925B019FEEE /* unzip.c */; settings = {COMPILER_FLAGS = ""; }; }; + 6BB503736AA94711A81D26D3 /* FBXUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E6332CD992D447CA910DA456 /* FBXUtil.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 6C434551EB1F43C9AE9AE538 /* OgreMaterial.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F75457C6D026451B9267B65E /* OgreMaterial.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 6F9F7543873B40A3832D1703 /* FBXParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5F373DF3B03B4B848B78EAD2 /* FBXParser.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 7277E86702084F3D8F7F2595 /* IFCReaderGen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3F5D1E6368384D429BA29D5A /* IFCReaderGen.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 74DCE45262FD417BB86348AC /* STEPFileReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDE3ECA98173418A9F997992 /* STEPFileReader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 765FA1339C83494B9D32D909 /* PretransformVertices.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 023C115651B54570AA2040DB /* PretransformVertices.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 7C3E0E5CFEEF403B8DC8E0DA /* FBXModel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A61BDC559CE4186B03C0396 /* FBXModel.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 7FD9BBB637FC44A995751DD1 /* PlyExporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E51043448F1744FFA78526D5 /* PlyExporter.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 8093E235B7A24B50809263BC /* SplitByBoneCountProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99A4349D505F4CC593F48CF6 /* SplitByBoneCountProcess.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 813894EA73344FDD86C37085 /* shapes.cc in Sources */ = {isa = PBXBuildFile; fileRef = AE00939F150F413780C8AAD7 /* shapes.cc */; settings = {COMPILER_FLAGS = ""; }; }; + 833DBC32CB4A411CA2E1FBF4 /* advancing_front.cc in Sources */ = {isa = PBXBuildFile; fileRef = B72D0BA3EF66439F8D582ED3 /* advancing_front.cc */; settings = {COMPILER_FLAGS = ""; }; }; + 843E0AFA420542EF8E80C4F6 /* SceneCombiner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 73A3D87FF2C04C3BA3684F54 /* SceneCombiner.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 84BA05FFC4B84434A4F2865A /* ObjFileImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 862131D4574B4CABA5EC957B /* ObjFileImporter.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 856922366B6F4D088324016F /* ObjFileParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ACF73EEAB2424213BF7158D5 /* ObjFileParser.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 869150F5FA334A739CA55ED5 /* IRRShared.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CC54A231FF6B4B0CABCFD167 /* IRRShared.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 86FA5A1954F54AE1980D50E7 /* FixNormalsStep.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C54518F708BA4A328D5D7325 /* FixNormalsStep.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 877F5B1F1C3543C18CFB38CD /* AssimpCExport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A1A9535EDF9A4FF2B8DABD7D /* AssimpCExport.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 8804DB0DABA64EFEB683E3F7 /* BlenderLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 906F71D342544BF381E1318E /* BlenderLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 880BBABBF77942EEA35AEFC4 /* IRRMeshLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD7FFD53046F4AEB898C0832 /* IRRMeshLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 89939A908EA344F685D3EC4D /* cdt.cc in Sources */ = {isa = PBXBuildFile; fileRef = 849EC6315E4A4E5FA06521EA /* cdt.cc */; settings = {COMPILER_FLAGS = ""; }; }; + 89C0A1FBD2414597B3F17EBB /* 3DSLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02E9476D129940BF84DE6682 /* 3DSLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 8A3CB60001A3485B859AAA00 /* FBXDeformer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9855496CEA774F4FA7FBB862 /* FBXDeformer.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 8C16784DF44B4DB5A9051449 /* IFCOpenings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 74679D2078FD46ED9AC73355 /* IFCOpenings.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 90CB3F9403F04B91A033FA6D /* SGSpatialSort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52836A0629E24447B924750A /* SGSpatialSort.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 92642F0078664ACAA4578492 /* OgreBinarySerializer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 56ADEC4899C047F2839AD791 /* OgreBinarySerializer.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 93C93490D1A645159F49630E /* sweep.cc in Sources */ = {isa = PBXBuildFile; fileRef = 49E993CD86A346869AF473BC /* sweep.cc */; settings = {COMPILER_FLAGS = ""; }; }; + 947A52B0651F4B67BB5A04EF /* ScenePreprocessor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1775DE08FC8647EB896A0FB3 /* ScenePreprocessor.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 9636ACD2FDBC4E809B9FDE46 /* DefaultLogger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A9E9EB834E09420197C3FB8C /* DefaultLogger.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 98E562C54EC844AA96551B41 /* COBLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C84DA0E6CE13493D833BA1C1 /* COBLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 9DE80CA157384A8AA191C9B2 /* AssimpPCH.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C16ECC01B4954B07AB547D6C /* AssimpPCH.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + A0285A7F436243969EF1241D /* FBXDocumentUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB38E7E7661842448F008372 /* FBXDocumentUtil.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + A201839885854EA09DF6F9B5 /* Q3BSPFileParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A60A00727F04E049CF3AE33 /* Q3BSPFileParser.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + A2437AE5CC194212B02F55F6 /* FBXNodeAttribute.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33B70115CA54405F895BA471 /* FBXNodeAttribute.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + A2D1DCC827B0499B9CD5A0D6 /* 3DSExporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ECCBBF2D75A44335AB93C84A /* 3DSExporter.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + A2E37983FB5F43A9A65C6F97 /* CSMLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 77908990BEF04D0881E8AE80 /* CSMLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + A4352EB42E754AEBAE139C8B /* ConvertUTF.c in Sources */ = {isa = PBXBuildFile; fileRef = 9A0960F123634603B15EEA38 /* ConvertUTF.c */; settings = {COMPILER_FLAGS = ""; }; }; + A50FB7E42BEA428299BED42A /* Q3BSPZipArchive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43C75175738C4119871E8BB0 /* Q3BSPZipArchive.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + A5FC512D048D4BFFAD960679 /* IFCCurve.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2E7FD92FFCF441B0A60FC8B4 /* IFCCurve.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + A8E506EA650F4D3DB504953D /* FBXAnimation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EAD34F1AA6664B6B935C9421 /* FBXAnimation.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + A985EFF885964FB09421FDA6 /* STEPFileEncoding.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E11A39E91576445599DF2AC4 /* STEPFileEncoding.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + AA55FAFEE2184A3F8464AFC7 /* ColladaLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A4706D216414D4F8AA72EC9 /* ColladaLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + AC4098FF84BB45D49101F555 /* LimitBoneWeightsProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E065DB38B0284196A9283CA3 /* LimitBoneWeightsProcess.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + AD249481F4174272BB86D4F2 /* PlyParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D504725E540109530E254 /* PlyParser.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + AF87AB1D5F124C63851EF06D /* LWSLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AFF41974881F466A9561BE4B /* LWSLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + B0F2D168DB044D4A93BB59F5 /* Q3DLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C5178B3983F147F3B9BD8217 /* Q3DLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + B151BDC341654FA681214ACF /* IFCProfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46E9F455A3284DB399986293 /* IFCProfile.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + B499F78FF5874465B1AA1ECE /* Importer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9472EFB6831740DD91471337 /* Importer.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + B99026162B084974A1299A64 /* STLLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4D2F1605B9484B08BB33402D /* STLLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + BABACE2F925443479F870954 /* STLExporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 89D2D359BD854D8AA60CB720 /* STLExporter.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + BAE97CFFFDE34E9BA9E0B480 /* RemoveComments.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6A86069DEEDC42B88634F78D /* RemoveComments.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + BE20AEE5126B4AC6AAC005F4 /* ObjFileMtlImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4108529663904025B21E526B /* ObjFileMtlImporter.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + C0264BCE748E464596BF449C /* XGLLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8E395349546A4FDF843E6963 /* XGLLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + C3ADFEA536BF4FF3B6C9F587 /* GenVertexNormalsProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A0AED12A1A6D4635A8CFB65A /* GenVertexNormalsProcess.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + C4F211D64AC348FDB8D7C67C /* FBXImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B4C688FA08F44716855CDD3C /* FBXImporter.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + C715213375A24A18A54D82F8 /* ColladaParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 420D77ED33554D54AA4D50EF /* ColladaParser.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + C8D153E801784E1CAECCC9F1 /* MDLMaterialLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CEC69808E1844C23B95D3475 /* MDLMaterialLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + C97C468599E940F892D2FCD1 /* FBXMaterial.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EE6163EB035149A6B8139DB8 /* FBXMaterial.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + CB2FC9139C4146F2963F7936 /* BVHLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C80B9A3AF4204AE08AA50BAE /* BVHLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + D1E81A09A0D24710A4FDE44F /* BlenderDNA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B65258E349704523BC43904D /* BlenderDNA.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + D4CAA1A48B574883B37969A2 /* LWOLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5A4E05386C094B809A315A07 /* LWOLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + D5909BAE18664A6FA736EC80 /* AssxmlExporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B3E8A1BEF8E74F04AE06871B /* AssxmlExporter.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + DAE0A20354BE4889A9D918A0 /* IFCMaterial.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0014AE5E87A74AAA9EF0EC4B /* IFCMaterial.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + DAED741B6225426EBEAF5C63 /* ConvertToLHProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92D8734FFF9742B39A371B70 /* ConvertToLHProcess.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + DCE1B99871964E928F5B4C91 /* IFCBoolean.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 285D1FDA48EC4DD8933B603E /* IFCBoolean.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + DDFBB8B2B78B4149B8D0785D /* SortByPTypeProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BD9A81E0E27E44718609615B /* SortByPTypeProcess.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + DECFBA5CCE374CB0B5482B70 /* ASELoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C477FA4D89548F1BCEDC5A0 /* ASELoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + DFC61ACABFFE405CA2D81D97 /* Subdivision.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBDEB63CFEB4F2EAA95358D /* Subdivision.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + E2302FC0DE0F4713AF4AE53F /* StandardShapes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C18C5023460E4D17B8C922D7 /* StandardShapes.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + E3BA3531AA8943DF8AF5215C /* RemoveVCProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FB4ABA17AF264257BDA4D921 /* RemoveVCProcess.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + E3E3C9BAAAE14737BFBDB7AE /* SpatialSort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8EEC6646FC044D1E9658A590 /* SpatialSort.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + E846D2F46E724308B3762235 /* Q3BSPFileImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A88D56FBEA084A3EA9A0ECB3 /* Q3BSPFileImporter.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + E89E29B47CA84BF38B5CC0D5 /* TriangulateProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A0AC303D18A48A69AB3BC03 /* TriangulateProcess.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + EC253D2452644205BD59E69B /* FBXProperties.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9D203F78B24C4D7E8E2084A3 /* FBXProperties.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + ED1C236FBB204757A45E685C /* OgreImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 923283A9791E4B4E86D623FC /* OgreImporter.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + EDA07283EFBC457CB0331971 /* MDCLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35E4944C052A4C91BF31DE5F /* MDCLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + F0430145F6F24B03AD9E2394 /* FBXTokenizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CF07D05DC86F4C98BC42FDCF /* FBXTokenizer.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + F1B541BC242D4E178B31FEDC /* DefaultIOStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9FEF4D69EFC4605A4F752E5 /* DefaultIOStream.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + F4B87C84ADE24C1D8950F229 /* AssbinLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D9FEEF58B24548F782A5D53C /* AssbinLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + F555CEC0C5D349FB855E01B1 /* MD2Loader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49B655CCE1314D4E8A94B371 /* MD2Loader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + F576B26DE4C944E6AC9A5E4C /* ImproveCacheLocality.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 70D5FDFA995E45E6A3E8FD37 /* ImproveCacheLocality.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + F632A255678844DEBD7DF103 /* MS3DLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7A990C6FF244DC397B7BA7C /* MS3DLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + F64BCE7A381744CCA4CE323A /* BlenderBMesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 603AFA882AFF49AEAC2C8FA2 /* BlenderBMesh.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + F66B9EDC7AAA4013B6651BF1 /* clipper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 59F8A11A7AED45CC94CEDF28 /* clipper.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + F70C84CC28084469B0171A67 /* ValidateDataStructure.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0EF4F7A237F648C2809A8F31 /* ValidateDataStructure.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + F91C37C0C4424003ABCB1088 /* PlyLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 409C98EE093C499B8A574CA9 /* PlyLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + FBC467B84AFD4089B1B35B67 /* FindInvalidDataProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9B4221AA0AD2418FAA45EB64 /* FindInvalidDataProcess.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + FD598E7E17A84C29A4C0F3F4 /* BlenderTessellator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 12C5DD7A285042EDB1897FAE /* BlenderTessellator.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + FE0CF0380CE24DFA9DF0964D /* FindInstancesProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C9A101D1311C4E77AAEDD94C /* FindInstancesProcess.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + FE6A140ABE3444D38A5303AD /* LWOBLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D629F6BF53864979B7619067 /* LWOBLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + FEBD430870494EE2BFDAF420 /* SkeletonMeshBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9B2827B3E64147E08A5AD334 /* SkeletonMeshBuilder.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + FF8AADE5437849E2AEE95E37 /* GenFaceNormalsProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 982AE676D2364350B1FBD095 /* GenFaceNormalsProcess.cpp */; settings = {COMPILER_FLAGS = ""; }; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 0014AE5E87A74AAA9EF0EC4B /* IFCMaterial.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = IFCMaterial.cpp; path = code/IFCMaterial.cpp; sourceTree = SOURCE_ROOT; }; + 005DFE3B6FFC4BEBB7055330 /* ObjFileData.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = ObjFileData.h; path = code/ObjFileData.h; sourceTree = SOURCE_ROOT; }; + 00EB692107B84590B0560BFB /* MD4FileData.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = MD4FileData.h; path = code/MD4FileData.h; sourceTree = SOURCE_ROOT; }; + 023C115651B54570AA2040DB /* PretransformVertices.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = PretransformVertices.cpp; path = code/PretransformVertices.cpp; sourceTree = SOURCE_ROOT; }; + 02587469A85540EE875B04B5 /* heapsort.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = heapsort.h; path = contrib/irrXML/heapsort.h; sourceTree = SOURCE_ROOT; }; + 02E9476D129940BF84DE6682 /* 3DSLoader.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = 3DSLoader.cpp; path = code/3DSLoader.cpp; sourceTree = SOURCE_ROOT; }; + 0535CB113239433DA7CD7FDE /* color4.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = color4.h; path = include/assimp/color4.h; sourceTree = SOURCE_ROOT; }; + 05EA73C462244F1791039BFB /* material.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = material.h; path = include/assimp/material.h; sourceTree = SOURCE_ROOT; }; + 06DB494DCE4D47FDA00E8B35 /* XFileImporter.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = XFileImporter.cpp; path = code/XFileImporter.cpp; sourceTree = SOURCE_ROOT; }; + 073189BEE7A5466B9EE817D4 /* matrix3x3.inl */ = {isa = PBXFileReference; explicitFileType = sourcecode; fileEncoding = 4; name = matrix3x3.inl; path = include/assimp/matrix3x3.inl; sourceTree = SOURCE_ROOT; }; + 079B3C75D1014265959C427D /* color4.inl */ = {isa = PBXFileReference; explicitFileType = sourcecode; fileEncoding = 4; name = color4.inl; path = include/assimp/color4.inl; sourceTree = SOURCE_ROOT; }; + 08E8379F20984AD59515AD95 /* MD3FileData.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = MD3FileData.h; path = code/MD3FileData.h; sourceTree = SOURCE_ROOT; }; + 0A941971CBF04E8D900E9799 /* JoinVerticesProcess.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = JoinVerticesProcess.h; path = code/JoinVerticesProcess.h; sourceTree = SOURCE_ROOT; }; + 0AA53AD6095A4D1088431EED /* MakeVerboseFormat.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = MakeVerboseFormat.h; path = code/MakeVerboseFormat.h; sourceTree = SOURCE_ROOT; }; + 0AAF26EBF0A64ABDB840BA64 /* VertexTriangleAdjacency.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = VertexTriangleAdjacency.cpp; path = code/VertexTriangleAdjacency.cpp; sourceTree = SOURCE_ROOT; }; + 0B519CCAB4B241E59C567077 /* 3DSExporter.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = 3DSExporter.h; path = code/3DSExporter.h; sourceTree = SOURCE_ROOT; }; + 0BC5FD00572F4C58B267A0EC /* MD5Parser.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = MD5Parser.cpp; path = code/MD5Parser.cpp; sourceTree = SOURCE_ROOT; }; + 0C1B00249A554394A4F9CF2A /* ParsingUtils.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = ParsingUtils.h; path = code/ParsingUtils.h; sourceTree = SOURCE_ROOT; }; + 0CCD090F58EB40ACBBDBBDEE /* AssbinLoader.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = AssbinLoader.h; path = code/AssbinLoader.h; sourceTree = SOURCE_ROOT; }; + 0D6E8E292F594A2DAFF53564 /* NFFLoader.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = NFFLoader.cpp; path = code/NFFLoader.cpp; sourceTree = SOURCE_ROOT; }; + 0EF256EC06E345EB930772EC /* FBXDocument.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = FBXDocument.h; path = code/FBXDocument.h; sourceTree = SOURCE_ROOT; }; + 0EF4F7A237F648C2809A8F31 /* ValidateDataStructure.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = ValidateDataStructure.cpp; path = code/ValidateDataStructure.cpp; sourceTree = SOURCE_ROOT; }; + 0FBF026F27F340AD9FABAF02 /* GenFaceNormalsProcess.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = GenFaceNormalsProcess.h; path = code/GenFaceNormalsProcess.h; sourceTree = SOURCE_ROOT; }; + 101172E4EF2E43D988B6B571 /* PretransformVertices.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = PretransformVertices.h; path = code/PretransformVertices.h; sourceTree = SOURCE_ROOT; }; + 1011FC45108745A7BBA98904 /* IRRLoader.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = IRRLoader.h; path = code/IRRLoader.h; sourceTree = SOURCE_ROOT; }; + 10238FBD7A9D401A82D667CB /* Bitmap.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = Bitmap.cpp; path = code/Bitmap.cpp; sourceTree = SOURCE_ROOT; }; + 10E9B0497D844A10BC759A09 /* matrix3x3.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = matrix3x3.h; path = include/assimp/matrix3x3.h; sourceTree = SOURCE_ROOT; }; + 1108AC28566B4D2B9F27C691 /* FBXBinaryTokenizer.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = FBXBinaryTokenizer.cpp; path = code/FBXBinaryTokenizer.cpp; sourceTree = SOURCE_ROOT; }; + 12C5DD7A285042EDB1897FAE /* BlenderTessellator.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = BlenderTessellator.cpp; path = code/BlenderTessellator.cpp; sourceTree = SOURCE_ROOT; }; + 12E167EBA81B4CD3A241D7AF /* irrXML.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = irrXML.h; path = contrib/irrXML/irrXML.h; sourceTree = SOURCE_ROOT; }; + 137A552C590C4E4BBBB1EE31 /* libassimp.3.1.1.a */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; path = libassimp.3.1.1.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 139DFC029C4C44B09952C645 /* material.inl */ = {isa = PBXFileReference; explicitFileType = sourcecode; fileEncoding = 4; name = material.inl; path = include/assimp/material.inl; sourceTree = SOURCE_ROOT; }; + 13BFADA520C04B15AE256CC2 /* IFCUtil.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = IFCUtil.h; path = code/IFCUtil.h; sourceTree = SOURCE_ROOT; }; + 1520A11AA6E54812939B1FBB /* FileLogStream.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = FileLogStream.h; path = code/FileLogStream.h; sourceTree = SOURCE_ROOT; }; + 15221A74FC9C4B2AAA7306E3 /* 3DSConverter.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = 3DSConverter.cpp; path = code/3DSConverter.cpp; sourceTree = SOURCE_ROOT; }; + 1533BE4C09F1430C8BF4D248 /* Vertex.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = Vertex.h; path = code/Vertex.h; sourceTree = SOURCE_ROOT; }; + 157C3CC81232428FA535E05F /* BlenderLoader.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = BlenderLoader.h; path = code/BlenderLoader.h; sourceTree = SOURCE_ROOT; }; + 16437E08A946431EB2EFA3E0 /* SortByPTypeProcess.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = SortByPTypeProcess.h; path = code/SortByPTypeProcess.h; sourceTree = SOURCE_ROOT; }; + 1775DE08FC8647EB896A0FB3 /* ScenePreprocessor.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = ScenePreprocessor.cpp; path = code/ScenePreprocessor.cpp; sourceTree = SOURCE_ROOT; }; + 180177D50FDA4C10AD629DC2 /* ObjFileMtlImporter.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = ObjFileMtlImporter.h; path = code/ObjFileMtlImporter.h; sourceTree = SOURCE_ROOT; }; + 1A0AC303D18A48A69AB3BC03 /* TriangulateProcess.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = TriangulateProcess.cpp; path = code/TriangulateProcess.cpp; sourceTree = SOURCE_ROOT; }; + 1A4706D216414D4F8AA72EC9 /* ColladaLoader.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = ColladaLoader.cpp; path = code/ColladaLoader.cpp; sourceTree = SOURCE_ROOT; }; + 1A61BDC559CE4186B03C0396 /* FBXModel.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = FBXModel.cpp; path = code/FBXModel.cpp; sourceTree = SOURCE_ROOT; }; + 1AF1EE8EFE594A40ACE03D19 /* fast_atof.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = fast_atof.h; path = code/fast_atof.h; sourceTree = SOURCE_ROOT; }; + 1BC6B0FE92DD4F38803BC17B /* CSMLoader.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = CSMLoader.h; path = code/CSMLoader.h; sourceTree = SOURCE_ROOT; }; + 1C0527629078403F81CFD117 /* ColladaExporter.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = ColladaExporter.cpp; path = code/ColladaExporter.cpp; sourceTree = SOURCE_ROOT; }; + 1CBCEE37D89145F19F23F036 /* MD3Loader.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = MD3Loader.h; path = code/MD3Loader.h; sourceTree = SOURCE_ROOT; }; + 1D4A669762194B9D9A26DD20 /* RawLoader.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = RawLoader.cpp; path = code/RawLoader.cpp; sourceTree = SOURCE_ROOT; }; + 1D502654EF864101A2DA9476 /* DefaultIOSystem.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = DefaultIOSystem.cpp; path = code/DefaultIOSystem.cpp; sourceTree = SOURCE_ROOT; }; + 1DC56C794E434BA28E5CCC36 /* format.hpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; name = format.hpp; path = code/BoostWorkaround/boost/format.hpp; sourceTree = SOURCE_ROOT; }; + 1ED21FC57A384CE6B4F53C0C /* LWOMaterial.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = LWOMaterial.cpp; path = code/LWOMaterial.cpp; sourceTree = SOURCE_ROOT; }; + 1FC965B1F11B45F98051C565 /* ObjFileImporter.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = ObjFileImporter.h; path = code/ObjFileImporter.h; sourceTree = SOURCE_ROOT; }; + 21B797DAB0E0427C9339AE0F /* MakeVerboseFormat.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = MakeVerboseFormat.cpp; path = code/MakeVerboseFormat.cpp; sourceTree = SOURCE_ROOT; }; + 21E21BE7CB364AC3AB81E54C /* MD2FileData.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = MD2FileData.h; path = code/MD2FileData.h; sourceTree = SOURCE_ROOT; }; + 22E66A720E694DAF9469EB92 /* ByteSwap.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = ByteSwap.h; path = code/ByteSwap.h; sourceTree = SOURCE_ROOT; }; + 23097CBD64E343738B8F22EE /* BlobIOSystem.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = BlobIOSystem.h; path = code/BlobIOSystem.h; sourceTree = SOURCE_ROOT; }; + 262DFE65C6D34442AA79D15A /* qnan.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = qnan.h; path = code/qnan.h; sourceTree = SOURCE_ROOT; }; + 267A74499024423A86150697 /* cimport.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = cimport.h; path = include/assimp/cimport.h; sourceTree = SOURCE_ROOT; }; + 267D593135514108B7DEF072 /* sweep_context.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = sweep_context.h; path = contrib/poly2tri/poly2tri/sweep/sweep_context.h; sourceTree = SOURCE_ROOT; }; + 26BF681530B04B73961997CB /* FBXCompileConfig.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = FBXCompileConfig.h; path = code/FBXCompileConfig.h; sourceTree = SOURCE_ROOT; }; + 27605E75944D41B0B98260A3 /* ASEParser.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = ASEParser.h; path = code/ASEParser.h; sourceTree = SOURCE_ROOT; }; + 278FB5C8BD814F2DAE04A1C7 /* pstdint.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = pstdint.h; path = include/assimp/Compiler/pstdint.h; sourceTree = SOURCE_ROOT; }; + 279D2A482FE9402A8F7EC441 /* quaternion.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = quaternion.h; path = include/assimp/quaternion.h; sourceTree = SOURCE_ROOT; }; + 27F2019E621B4CDA94DD5270 /* UnrealLoader.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = UnrealLoader.h; path = code/UnrealLoader.h; sourceTree = SOURCE_ROOT; }; + 285D1FDA48EC4DD8933B603E /* IFCBoolean.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = IFCBoolean.cpp; path = code/IFCBoolean.cpp; sourceTree = SOURCE_ROOT; }; + 28A938B21261484998F68F4A /* FindInstancesProcess.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = FindInstancesProcess.h; path = code/FindInstancesProcess.h; sourceTree = SOURCE_ROOT; }; + 296407DE471C4F298742FB59 /* StandardShapes.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = StandardShapes.h; path = code/StandardShapes.h; sourceTree = SOURCE_ROOT; }; + 2ABBB4561E72413EB40702C3 /* ComputeUVMappingProcess.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = ComputeUVMappingProcess.cpp; path = code/ComputeUVMappingProcess.cpp; sourceTree = SOURCE_ROOT; }; + 2AC344FBB0C34D49800F4B8A /* GenVertexNormalsProcess.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = GenVertexNormalsProcess.h; path = code/GenVertexNormalsProcess.h; sourceTree = SOURCE_ROOT; }; + 2ACC87E846AE4E4A86E1AEF4 /* OptimizeMeshes.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = OptimizeMeshes.cpp; path = code/OptimizeMeshes.cpp; sourceTree = SOURCE_ROOT; }; + 2BE34AF1CE0C4767ACE21597 /* IFCLoader.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = IFCLoader.h; path = code/IFCLoader.h; sourceTree = SOURCE_ROOT; }; + 2C4D504725E540109530E254 /* PlyParser.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = PlyParser.cpp; path = code/PlyParser.cpp; sourceTree = SOURCE_ROOT; }; + 2DCF6F156A3A4B4C807E5368 /* SmoothingGroups.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = SmoothingGroups.h; path = code/SmoothingGroups.h; sourceTree = SOURCE_ROOT; }; + 2E7FD92FFCF441B0A60FC8B4 /* IFCCurve.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = IFCCurve.cpp; path = code/IFCCurve.cpp; sourceTree = SOURCE_ROOT; }; + 2F34A6A3C4104625A52BF7C2 /* cexport.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = cexport.h; path = include/assimp/cexport.h; sourceTree = SOURCE_ROOT; }; + 3106D75C13874F5AB3EBBFE7 /* BlenderModifier.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = BlenderModifier.cpp; path = code/BlenderModifier.cpp; sourceTree = SOURCE_ROOT; }; + 32170F499DAC4E4595AF6D6B /* BaseImporter.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = BaseImporter.h; path = code/BaseImporter.h; sourceTree = SOURCE_ROOT; }; + 3267EBBA6EEB435F83FF25E4 /* IFCGeometry.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = IFCGeometry.cpp; path = code/IFCGeometry.cpp; sourceTree = SOURCE_ROOT; }; + 32CC68350B7640ACA7C83DDA /* DefaultIOStream.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = DefaultIOStream.h; path = code/DefaultIOStream.h; sourceTree = SOURCE_ROOT; }; + 333F4676A92043739F5A9D32 /* ObjFileParser.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = ObjFileParser.h; path = code/ObjFileParser.h; sourceTree = SOURCE_ROOT; }; + 339E56B5FD264481BBF21835 /* CInterfaceIOWrapper.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = CInterfaceIOWrapper.h; path = code/CInterfaceIOWrapper.h; sourceTree = SOURCE_ROOT; }; + 33B70115CA54405F895BA471 /* FBXNodeAttribute.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = FBXNodeAttribute.cpp; path = code/FBXNodeAttribute.cpp; sourceTree = SOURCE_ROOT; }; + 3551D90CCED1454A8B912066 /* XFileParser.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = XFileParser.h; path = code/XFileParser.h; sourceTree = SOURCE_ROOT; }; + 35A9B50143214C63A956FA27 /* ConvertToLHProcess.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = ConvertToLHProcess.h; path = code/ConvertToLHProcess.h; sourceTree = SOURCE_ROOT; }; + 35E4944C052A4C91BF31DE5F /* MDCLoader.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = MDCLoader.cpp; path = code/MDCLoader.cpp; sourceTree = SOURCE_ROOT; }; + 37A3E0E2BB484DD8B9FCCA5E /* NDOLoader.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = NDOLoader.h; path = code/NDOLoader.h; sourceTree = SOURCE_ROOT; }; + 3ACFF3FC39C74C4A966C0FEA /* GenericProperty.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = GenericProperty.h; path = code/GenericProperty.h; sourceTree = SOURCE_ROOT; }; + 3B407EAF162843CBA46BC9D4 /* scene.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = scene.h; path = include/assimp/scene.h; sourceTree = SOURCE_ROOT; }; + 3B8FD96D46314ACD8F157AC3 /* UnrealLoader.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = UnrealLoader.cpp; path = code/UnrealLoader.cpp; sourceTree = SOURCE_ROOT; }; + 3E84DEFC1E0646AD82F79998 /* shared_ptr.hpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; name = shared_ptr.hpp; path = code/BoostWorkaround/boost/shared_ptr.hpp; sourceTree = SOURCE_ROOT; }; + 3F5D1E6368384D429BA29D5A /* IFCReaderGen.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = IFCReaderGen.cpp; path = code/IFCReaderGen.cpp; sourceTree = SOURCE_ROOT; }; + 409C98EE093C499B8A574CA9 /* PlyLoader.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = PlyLoader.cpp; path = code/PlyLoader.cpp; sourceTree = SOURCE_ROOT; }; + 4108529663904025B21E526B /* ObjFileMtlImporter.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = ObjFileMtlImporter.cpp; path = code/ObjFileMtlImporter.cpp; sourceTree = SOURCE_ROOT; }; + 41C2F6D564924BF4ACE75CAC /* postprocess.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = postprocess.h; path = include/assimp/postprocess.h; sourceTree = SOURCE_ROOT; }; + 420D77ED33554D54AA4D50EF /* ColladaParser.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = ColladaParser.cpp; path = code/ColladaParser.cpp; sourceTree = SOURCE_ROOT; }; + 42E110B9E6924AF9B55AE65A /* FBXMeshGeometry.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = FBXMeshGeometry.cpp; path = code/FBXMeshGeometry.cpp; sourceTree = SOURCE_ROOT; }; + 42E68041B1C442E3B49FC304 /* B3DImporter.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = B3DImporter.h; path = code/B3DImporter.h; sourceTree = SOURCE_ROOT; }; + 435DC362E63D4CCBA68656D3 /* XFileExporter.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = XFileExporter.cpp; path = code/XFileExporter.cpp; sourceTree = SOURCE_ROOT; }; + 43899EB0B0704A9DB8F0C54F /* BlenderDNA.inl */ = {isa = PBXFileReference; explicitFileType = sourcecode; fileEncoding = 4; name = BlenderDNA.inl; path = code/BlenderDNA.inl; sourceTree = SOURCE_ROOT; }; + 43ABFF591F374920A5E18A24 /* HMPLoader.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = HMPLoader.cpp; path = code/HMPLoader.cpp; sourceTree = SOURCE_ROOT; }; + 43C75175738C4119871E8BB0 /* Q3BSPZipArchive.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = Q3BSPZipArchive.cpp; path = code/Q3BSPZipArchive.cpp; sourceTree = SOURCE_ROOT; }; + 43FC808D2F4745ACB06A9D33 /* MD5Parser.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = MD5Parser.h; path = code/MD5Parser.h; sourceTree = SOURCE_ROOT; }; + 445F70426FCC42F088405E86 /* COBLoader.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = COBLoader.h; path = code/COBLoader.h; sourceTree = SOURCE_ROOT; }; + 4493838DDEE841BF96A0F008 /* matrix4x4.inl */ = {isa = PBXFileReference; explicitFileType = sourcecode; fileEncoding = 4; name = matrix4x4.inl; path = include/assimp/matrix4x4.inl; sourceTree = SOURCE_ROOT; }; + 4568875B66584E12AA1538C7 /* BlenderBMesh.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = BlenderBMesh.h; path = code/BlenderBMesh.h; sourceTree = SOURCE_ROOT; }; + 45BC2EB74251493CBBFAEB5D /* SkeletonMeshBuilder.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = SkeletonMeshBuilder.h; path = code/SkeletonMeshBuilder.h; sourceTree = SOURCE_ROOT; }; + 45E342A1499E4F03ADD49028 /* BVHLoader.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = BVHLoader.h; path = code/BVHLoader.h; sourceTree = SOURCE_ROOT; }; + 45F6A2B351AB4B749E55B299 /* PlyParser.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = PlyParser.h; path = code/PlyParser.h; sourceTree = SOURCE_ROOT; }; + 466D6B9A7CCD402D9AA87071 /* DXFLoader.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = DXFLoader.cpp; path = code/DXFLoader.cpp; sourceTree = SOURCE_ROOT; }; + 46E9F455A3284DB399986293 /* IFCProfile.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = IFCProfile.cpp; path = code/IFCProfile.cpp; sourceTree = SOURCE_ROOT; }; + 4770D6DCA1854B4F9B85546A /* DeboneProcess.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = DeboneProcess.h; path = code/DeboneProcess.h; sourceTree = SOURCE_ROOT; }; + 47FF3063906E4786ABF0939B /* STEPFile.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = STEPFile.h; path = code/STEPFile.h; sourceTree = SOURCE_ROOT; }; + 4866DA5A7BFD49F79B61CBF8 /* TerragenLoader.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = TerragenLoader.cpp; path = code/TerragenLoader.cpp; sourceTree = SOURCE_ROOT; }; + 4936396409984881858E7B15 /* irrTypes.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = irrTypes.h; path = contrib/irrXML/irrTypes.h; sourceTree = SOURCE_ROOT; }; + 49AFF879142C4BA4865843DC /* Bitmap.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = Bitmap.h; path = code/Bitmap.h; sourceTree = SOURCE_ROOT; }; + 49B655CCE1314D4E8A94B371 /* MD2Loader.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = MD2Loader.cpp; path = code/MD2Loader.cpp; sourceTree = SOURCE_ROOT; }; + 49E993CD86A346869AF473BC /* sweep.cc */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = sweep.cc; path = contrib/poly2tri/poly2tri/sweep/sweep.cc; sourceTree = SOURCE_ROOT; }; + 49FE5C30FC854A3EBD0E9C19 /* irrArray.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = irrArray.h; path = contrib/irrXML/irrArray.h; sourceTree = SOURCE_ROOT; }; + 4A60A00727F04E049CF3AE33 /* Q3BSPFileParser.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = Q3BSPFileParser.cpp; path = code/Q3BSPFileParser.cpp; sourceTree = SOURCE_ROOT; }; + 4B571231CE2B464BBF1E853F /* FindDegenerates.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = FindDegenerates.h; path = code/FindDegenerates.h; sourceTree = SOURCE_ROOT; }; + 4BBDEB63CFEB4F2EAA95358D /* Subdivision.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = Subdivision.cpp; path = code/Subdivision.cpp; sourceTree = SOURCE_ROOT; }; + 4CBC1122A79D4F6C94E36CE3 /* StdOStreamLogStream.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = StdOStreamLogStream.h; path = code/StdOStreamLogStream.h; sourceTree = SOURCE_ROOT; }; + 4D2F1605B9484B08BB33402D /* STLLoader.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = STLLoader.cpp; path = code/STLLoader.cpp; sourceTree = SOURCE_ROOT; }; + 4D82A29A8BBF44E69E026F84 /* importerdesc.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = importerdesc.h; path = include/assimp/importerdesc.h; sourceTree = SOURCE_ROOT; }; + 4DABF3CB245F4246B0184513 /* ACLoader.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = ACLoader.h; path = code/ACLoader.h; sourceTree = SOURCE_ROOT; }; + 4FE1E4726B144AD1B922A1A0 /* ScenePreprocessor.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = ScenePreprocessor.h; path = code/ScenePreprocessor.h; sourceTree = SOURCE_ROOT; }; + 501B18C2B590455D8A3C3E78 /* XGLLoader.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = XGLLoader.h; path = code/XGLLoader.h; sourceTree = SOURCE_ROOT; }; + 50935A81362041BEADF18609 /* utils.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = utils.h; path = contrib/poly2tri/poly2tri/common/utils.h; sourceTree = SOURCE_ROOT; }; + 52836A0629E24447B924750A /* SGSpatialSort.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = SGSpatialSort.cpp; path = code/SGSpatialSort.cpp; sourceTree = SOURCE_ROOT; }; + 531FBC4210644C61954EA4C4 /* MD2Loader.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = MD2Loader.h; path = code/MD2Loader.h; sourceTree = SOURCE_ROOT; }; + 53537D08E9B44A25B43B697B /* XFileImporter.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = XFileImporter.h; path = code/XFileImporter.h; sourceTree = SOURCE_ROOT; }; + 5631CE86F56F458EA0E2415F /* HMPLoader.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = HMPLoader.h; path = code/HMPLoader.h; sourceTree = SOURCE_ROOT; }; + 563FBACCFD774BDEA4AEAC10 /* MD3Loader.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = MD3Loader.cpp; path = code/MD3Loader.cpp; sourceTree = SOURCE_ROOT; }; + 56ADEC4899C047F2839AD791 /* OgreBinarySerializer.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = OgreBinarySerializer.cpp; path = code/OgreBinarySerializer.cpp; sourceTree = SOURCE_ROOT; }; + 56CE07D64D114C4BAB6D9F08 /* Logger.hpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; name = Logger.hpp; path = include/assimp/Logger.hpp; sourceTree = SOURCE_ROOT; }; + 56DA1CDC223747F4AFBAF953 /* types.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = types.h; path = include/assimp/types.h; sourceTree = SOURCE_ROOT; }; + 59A1859480754E90B958CA85 /* BlenderTessellator.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = BlenderTessellator.h; path = code/BlenderTessellator.h; sourceTree = SOURCE_ROOT; }; + 59E3D32E3FC7438DB148537F /* IFCUtil.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = IFCUtil.cpp; path = code/IFCUtil.cpp; sourceTree = SOURCE_ROOT; }; + 59F8A11A7AED45CC94CEDF28 /* clipper.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = clipper.cpp; path = contrib/clipper/clipper.cpp; sourceTree = SOURCE_ROOT; }; + 5A4E05386C094B809A315A07 /* LWOLoader.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = LWOLoader.cpp; path = code/LWOLoader.cpp; sourceTree = SOURCE_ROOT; }; + 5C15EEB253204E8A8E0D0E38 /* Q3BSPFileParser.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = Q3BSPFileParser.h; path = code/Q3BSPFileParser.h; sourceTree = SOURCE_ROOT; }; + 5C1EA03E3AE24AA5A778B7F1 /* Profiler.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = Profiler.h; path = code/Profiler.h; sourceTree = SOURCE_ROOT; }; + 5D4E64EABD9548A59E9637AF /* irrString.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = irrString.h; path = contrib/irrXML/irrString.h; sourceTree = SOURCE_ROOT; }; + 5E10483FBE6D4F4594B460E0 /* sweep_context.cc */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = sweep_context.cc; path = contrib/poly2tri/poly2tri/sweep/sweep_context.cc; sourceTree = SOURCE_ROOT; }; + 5F373DF3B03B4B848B78EAD2 /* FBXParser.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = FBXParser.cpp; path = code/FBXParser.cpp; sourceTree = SOURCE_ROOT; }; + 5F84BDD0D5D345A2BF1E08E1 /* metadata.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = metadata.h; path = include/assimp/metadata.h; sourceTree = SOURCE_ROOT; }; + 5FBE72DCC6AC485ABCF89B8C /* ImproveCacheLocality.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = ImproveCacheLocality.h; path = code/ImproveCacheLocality.h; sourceTree = SOURCE_ROOT; }; + 603AFA882AFF49AEAC2C8FA2 /* BlenderBMesh.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = BlenderBMesh.cpp; path = code/BlenderBMesh.cpp; sourceTree = SOURCE_ROOT; }; + 6162B57DE81A4E538430056E /* IFCReaderGen.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = IFCReaderGen.h; path = code/IFCReaderGen.h; sourceTree = SOURCE_ROOT; }; + 621E96E95F60421EB6B4525C /* MDCLoader.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = MDCLoader.h; path = code/MDCLoader.h; sourceTree = SOURCE_ROOT; }; + 62E8551653634972ABBABCAD /* sweep.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = sweep.h; path = contrib/poly2tri/poly2tri/sweep/sweep.h; sourceTree = SOURCE_ROOT; }; + 6347FA5D391D4320B9457D3F /* MS3DLoader.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = MS3DLoader.h; path = code/MS3DLoader.h; sourceTree = SOURCE_ROOT; }; + 6389F68312384CFD847B1D13 /* AssbinExporter.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = AssbinExporter.cpp; path = code/AssbinExporter.cpp; sourceTree = SOURCE_ROOT; }; + 638B3F6AC17A435C9B86C86C /* ColladaExporter.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = ColladaExporter.h; path = code/ColladaExporter.h; sourceTree = SOURCE_ROOT; }; + 6454A961FAF44B3E9086D2F8 /* Q3BSPZipArchive.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = Q3BSPZipArchive.h; path = code/Q3BSPZipArchive.h; sourceTree = SOURCE_ROOT; }; + 64C6BACDA5DD4139AA26EE81 /* irrXML.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = irrXML.cpp; path = contrib/irrXML/irrXML.cpp; sourceTree = SOURCE_ROOT; }; + 657B9A15EE7A4B7BA519A969 /* LogStream.hpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; name = LogStream.hpp; path = include/assimp/LogStream.hpp; sourceTree = SOURCE_ROOT; }; + 670FE6DD7EDF421488F2F97F /* IRRMeshLoader.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = IRRMeshLoader.h; path = code/IRRMeshLoader.h; sourceTree = SOURCE_ROOT; }; + 680C392FFE0B4CC5ABC7CA64 /* LWOAnimation.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = LWOAnimation.cpp; path = code/LWOAnimation.cpp; sourceTree = SOURCE_ROOT; }; + 680FBD79376A41B690C405B8 /* LineSplitter.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = LineSplitter.h; path = code/LineSplitter.h; sourceTree = SOURCE_ROOT; }; + 68703F99581F49CB9E2B9F37 /* LWSLoader.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = LWSLoader.h; path = code/LWSLoader.h; sourceTree = SOURCE_ROOT; }; + 6981B16018CF46CAA54C0BAA /* ColladaLoader.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = ColladaLoader.h; path = code/ColladaLoader.h; sourceTree = SOURCE_ROOT; }; + 69AFF47737244CE3BD1653CC /* ProgressHandler.hpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; name = ProgressHandler.hpp; path = include/assimp/ProgressHandler.hpp; sourceTree = SOURCE_ROOT; }; + 6A86069DEEDC42B88634F78D /* RemoveComments.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = RemoveComments.cpp; path = code/RemoveComments.cpp; sourceTree = SOURCE_ROOT; }; + 6AC645CEB6F74AE5A62DF68B /* IFF.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = IFF.h; path = code/IFF.h; sourceTree = SOURCE_ROOT; }; + 6BAB32C8E06E43689FC5E7EA /* MD5Loader.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = MD5Loader.h; path = code/MD5Loader.h; sourceTree = SOURCE_ROOT; }; + 6CC21F1D0E4140FE923E4EE6 /* AssbinExporter.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = AssbinExporter.h; path = code/AssbinExporter.h; sourceTree = SOURCE_ROOT; }; + 6D72952403D04713A6451654 /* vector3.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = vector3.h; path = include/assimp/vector3.h; sourceTree = SOURCE_ROOT; }; + 6E20FCC571F144DDBD831CCB /* DeboneProcess.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = DeboneProcess.cpp; path = code/DeboneProcess.cpp; sourceTree = SOURCE_ROOT; }; + 6E82409E9D274D278971F3B0 /* Q3BSPFileData.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = Q3BSPFileData.h; path = code/Q3BSPFileData.h; sourceTree = SOURCE_ROOT; }; + 6F49958B5CCF423681133515 /* OgreParsingUtils.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = OgreParsingUtils.h; path = code/OgreParsingUtils.h; sourceTree = SOURCE_ROOT; }; + 6F65B6129F774AEDB8DC845A /* TargetAnimation.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = TargetAnimation.cpp; path = code/TargetAnimation.cpp; sourceTree = SOURCE_ROOT; }; + 6F88E78E61FC4A01BC30BE85 /* ConvertUTF.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = ConvertUTF.h; path = contrib/ConvertUTF/ConvertUTF.h; sourceTree = SOURCE_ROOT; }; + 705D30EE141A48F292783F0E /* Assimp.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = Assimp.cpp; path = code/Assimp.cpp; sourceTree = SOURCE_ROOT; }; + 70D5FDFA995E45E6A3E8FD37 /* ImproveCacheLocality.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = ImproveCacheLocality.cpp; path = code/ImproveCacheLocality.cpp; sourceTree = SOURCE_ROOT; }; + 71EAFDE1910B4A54AAAF2101 /* HMPFileData.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = HMPFileData.h; path = code/HMPFileData.h; sourceTree = SOURCE_ROOT; }; + 71F65BF6936E4E97A5933EF9 /* OgreImporter.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = OgreImporter.h; path = code/OgreImporter.h; sourceTree = SOURCE_ROOT; }; + 725DAD1CE04C4F64BDAB7037 /* ValidateDataStructure.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = ValidateDataStructure.h; path = code/ValidateDataStructure.h; sourceTree = SOURCE_ROOT; }; + 72832410F47C44E3BAE709C2 /* BlenderDNA.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = BlenderDNA.h; path = code/BlenderDNA.h; sourceTree = SOURCE_ROOT; }; + 72F2DF0B93CF4D3ABAD7513D /* LWOLoader.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = LWOLoader.h; path = code/LWOLoader.h; sourceTree = SOURCE_ROOT; }; + 72F637AC7D9E4FBFBB9201CE /* ioapi.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = ioapi.h; path = contrib/unzip/ioapi.h; sourceTree = SOURCE_ROOT; }; + 731205CAB88247C095E33412 /* Exporter.hpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; name = Exporter.hpp; path = include/assimp/Exporter.hpp; sourceTree = SOURCE_ROOT; }; + 73A3D87FF2C04C3BA3684F54 /* SceneCombiner.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = SceneCombiner.cpp; path = code/SceneCombiner.cpp; sourceTree = SOURCE_ROOT; }; + 74679D2078FD46ED9AC73355 /* IFCOpenings.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = IFCOpenings.cpp; path = code/IFCOpenings.cpp; sourceTree = SOURCE_ROOT; }; + 74C02A113B804568A7E39CBC /* XFileParser.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = XFileParser.cpp; path = code/XFileParser.cpp; sourceTree = SOURCE_ROOT; }; + 7644CE6B26D740258577EE9D /* scoped_ptr.hpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; name = scoped_ptr.hpp; path = code/BoostWorkaround/boost/scoped_ptr.hpp; sourceTree = SOURCE_ROOT; }; + 76773A53296549FFA43956A1 /* Q3DLoader.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = Q3DLoader.h; path = code/Q3DLoader.h; sourceTree = SOURCE_ROOT; }; + 76D801D898C4443D8240EDB7 /* BlenderSceneGen.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = BlenderSceneGen.h; path = code/BlenderSceneGen.h; sourceTree = SOURCE_ROOT; }; + 77908990BEF04D0881E8AE80 /* CSMLoader.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = CSMLoader.cpp; path = code/CSMLoader.cpp; sourceTree = SOURCE_ROOT; }; + 79A49EFE23E34E1CBA2E4377 /* OgreStructs.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = OgreStructs.cpp; path = code/OgreStructs.cpp; sourceTree = SOURCE_ROOT; }; + 7BDF90B124F74A39A5EB3B02 /* DXFLoader.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = DXFLoader.h; path = code/DXFLoader.h; sourceTree = SOURCE_ROOT; }; + 7C10178C0B7241DD874A0AF3 /* ColladaHelper.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = ColladaHelper.h; path = code/ColladaHelper.h; sourceTree = SOURCE_ROOT; }; + 7C477FA4D89548F1BCEDC5A0 /* ASELoader.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = ASELoader.cpp; path = code/ASELoader.cpp; sourceTree = SOURCE_ROOT; }; + 7C63156710964DEDAC0929BD /* HalfLifeFileData.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = HalfLifeFileData.h; path = code/HalfLifeFileData.h; sourceTree = SOURCE_ROOT; }; + 7CAF8A3096E04CB983B53CC1 /* BlenderIntermediate.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = BlenderIntermediate.h; path = code/BlenderIntermediate.h; sourceTree = SOURCE_ROOT; }; + 7DC4B0B5E57F4F4892CC823E /* MemoryIOWrapper.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = MemoryIOWrapper.h; path = code/MemoryIOWrapper.h; sourceTree = SOURCE_ROOT; }; + 7E8BA0D338C9433587BC6C35 /* StreamWriter.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = StreamWriter.h; path = code/StreamWriter.h; sourceTree = SOURCE_ROOT; }; + 7F29EF981AB26C4900E9D380 /* libz.1.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.1.dylib; path = ../../../../../../usr/lib/libz.1.dylib; sourceTree = ""; }; + 7FF72CB6E99E40E19AE0E64C /* MaterialSystem.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = MaterialSystem.cpp; path = code/MaterialSystem.cpp; sourceTree = SOURCE_ROOT; }; + 815702BED5644DD5B242F347 /* TerragenLoader.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = TerragenLoader.h; path = code/TerragenLoader.h; sourceTree = SOURCE_ROOT; }; + 8299401C3E4A43A18E887DC1 /* SGSpatialSort.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = SGSpatialSort.h; path = code/SGSpatialSort.h; sourceTree = SOURCE_ROOT; }; + 8343910BBD464297932B3CE0 /* FixNormalsStep.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = FixNormalsStep.h; path = code/FixNormalsStep.h; sourceTree = SOURCE_ROOT; }; + 8476FEE874C1404B9B4B9617 /* SceneCombiner.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = SceneCombiner.h; path = code/SceneCombiner.h; sourceTree = SOURCE_ROOT; }; + 849EC6315E4A4E5FA06521EA /* cdt.cc */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = cdt.cc; path = contrib/poly2tri/poly2tri/sweep/cdt.cc; sourceTree = SOURCE_ROOT; }; + 862131D4574B4CABA5EC957B /* ObjFileImporter.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = ObjFileImporter.cpp; path = code/ObjFileImporter.cpp; sourceTree = SOURCE_ROOT; }; + 86E296E459F94050ACBA3C63 /* IOSystem.hpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; name = IOSystem.hpp; path = include/assimp/IOSystem.hpp; sourceTree = SOURCE_ROOT; }; + 88ADA502481B403191BD35F0 /* STLExporter.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = STLExporter.h; path = code/STLExporter.h; sourceTree = SOURCE_ROOT; }; + 890E32C714444692AA016AE5 /* ProcessHelper.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = ProcessHelper.cpp; path = code/ProcessHelper.cpp; sourceTree = SOURCE_ROOT; }; + 89473420F7E448A7BE71FCBA /* FBXUtil.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = FBXUtil.h; path = code/FBXUtil.h; sourceTree = SOURCE_ROOT; }; + 89D2D359BD854D8AA60CB720 /* STLExporter.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = STLExporter.cpp; path = code/STLExporter.cpp; sourceTree = SOURCE_ROOT; }; + 8C9AEFFFF3B948148D32D76F /* shared_array.hpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; name = shared_array.hpp; path = code/BoostWorkaround/boost/shared_array.hpp; sourceTree = SOURCE_ROOT; }; + 8D53CC35AAED4CE8B9710E04 /* vector3.inl */ = {isa = PBXFileReference; explicitFileType = sourcecode; fileEncoding = 4; name = vector3.inl; path = include/assimp/vector3.inl; sourceTree = SOURCE_ROOT; }; + 8D977E197CA4477AB9F3278C /* NullLogger.hpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; name = NullLogger.hpp; path = include/assimp/NullLogger.hpp; sourceTree = SOURCE_ROOT; }; + 8E2108F568374F65ACE217D1 /* light.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = light.h; path = include/assimp/light.h; sourceTree = SOURCE_ROOT; }; + 8E395349546A4FDF843E6963 /* XGLLoader.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = XGLLoader.cpp; path = code/XGLLoader.cpp; sourceTree = SOURCE_ROOT; }; + 8EEC6646FC044D1E9658A590 /* SpatialSort.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = SpatialSort.cpp; path = code/SpatialSort.cpp; sourceTree = SOURCE_ROOT; }; + 8F4261792A60481DA04E6E1A /* XFileHelper.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = XFileHelper.h; path = code/XFileHelper.h; sourceTree = SOURCE_ROOT; }; + 8FE8B4781BB3406EB3452154 /* ObjTools.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = ObjTools.h; path = code/ObjTools.h; sourceTree = SOURCE_ROOT; }; + 904A696E49D540C2A880792B /* cdt.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = cdt.h; path = contrib/poly2tri/poly2tri/sweep/cdt.h; sourceTree = SOURCE_ROOT; }; + 906F71D342544BF381E1318E /* BlenderLoader.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = BlenderLoader.cpp; path = code/BlenderLoader.cpp; sourceTree = SOURCE_ROOT; }; + 90949C7A51E84D3595D71A6B /* config.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = config.h; path = include/assimp/config.h; sourceTree = SOURCE_ROOT; }; + 90DD6CA40A5E41458E11FF3E /* CalcTangentsProcess.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = CalcTangentsProcess.cpp; path = code/CalcTangentsProcess.cpp; sourceTree = SOURCE_ROOT; }; + 916456789C75419DB1436FAD /* OgreBinarySerializer.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = OgreBinarySerializer.h; path = code/OgreBinarySerializer.h; sourceTree = SOURCE_ROOT; }; + 91D49B3C51684882A01EA492 /* PlyLoader.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = PlyLoader.h; path = code/PlyLoader.h; sourceTree = SOURCE_ROOT; }; + 91EF6411C40946758A06144F /* ObjExporter.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = ObjExporter.h; path = code/ObjExporter.h; sourceTree = SOURCE_ROOT; }; + 91FF8B1DCC0644008AE34A04 /* FindInvalidDataProcess.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = FindInvalidDataProcess.h; path = code/FindInvalidDataProcess.h; sourceTree = SOURCE_ROOT; }; + 923283A9791E4B4E86D623FC /* OgreImporter.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = OgreImporter.cpp; path = code/OgreImporter.cpp; sourceTree = SOURCE_ROOT; }; + 926E8B7924144B349A88023D /* OptimizeGraph.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = OptimizeGraph.h; path = code/OptimizeGraph.h; sourceTree = SOURCE_ROOT; }; + 9293C5A353F9497A850E05D5 /* unzip.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = unzip.h; path = contrib/unzip/unzip.h; sourceTree = SOURCE_ROOT; }; + 929F59CCA32549EC884A5033 /* ASEParser.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = ASEParser.cpp; path = code/ASEParser.cpp; sourceTree = SOURCE_ROOT; }; + 92D8734FFF9742B39A371B70 /* ConvertToLHProcess.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = ConvertToLHProcess.cpp; path = code/ConvertToLHProcess.cpp; sourceTree = SOURCE_ROOT; }; + 9472EFB6831740DD91471337 /* Importer.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = Importer.cpp; path = code/Importer.cpp; sourceTree = SOURCE_ROOT; }; + 95641498F25A4F6FABBC03A4 /* MDCFileData.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = MDCFileData.h; path = code/MDCFileData.h; sourceTree = SOURCE_ROOT; }; + 957FBC18FED2484F83308E36 /* SpatialSort.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = SpatialSort.h; path = code/SpatialSort.h; sourceTree = SOURCE_ROOT; }; + 967D69AC1A344D4E988F0B2C /* common_factor_rt.hpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; name = common_factor_rt.hpp; path = code/BoostWorkaround/boost/math/common_factor_rt.hpp; sourceTree = SOURCE_ROOT; }; + 96A02CBA1AE642BD9519719D /* make_shared.hpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; name = make_shared.hpp; path = code/BoostWorkaround/boost/make_shared.hpp; sourceTree = SOURCE_ROOT; }; + 973D4231A4AA4925B019FEEE /* unzip.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.c; fileEncoding = 4; name = unzip.c; path = contrib/unzip/unzip.c; sourceTree = SOURCE_ROOT; }; + 9761D873B9604504B9AD7CD5 /* defs.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = defs.h; path = include/assimp/defs.h; sourceTree = SOURCE_ROOT; }; + 97914BDA4AA34081855BF16C /* ScenePrivate.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = ScenePrivate.h; path = code/ScenePrivate.h; sourceTree = SOURCE_ROOT; }; + 97DFA90F9D0C4B999C150B10 /* IRRLoader.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = IRRLoader.cpp; path = code/IRRLoader.cpp; sourceTree = SOURCE_ROOT; }; + 97F52051AF4F478FA77AABBC /* quaternion.inl */ = {isa = PBXFileReference; explicitFileType = sourcecode; fileEncoding = 4; name = quaternion.inl; path = include/assimp/quaternion.inl; sourceTree = SOURCE_ROOT; }; + 982AE676D2364350B1FBD095 /* GenFaceNormalsProcess.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = GenFaceNormalsProcess.cpp; path = code/GenFaceNormalsProcess.cpp; sourceTree = SOURCE_ROOT; }; + 9855496CEA774F4FA7FBB862 /* FBXDeformer.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = FBXDeformer.cpp; path = code/FBXDeformer.cpp; sourceTree = SOURCE_ROOT; }; + 99A4349D505F4CC593F48CF6 /* SplitByBoneCountProcess.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = SplitByBoneCountProcess.cpp; path = code/SplitByBoneCountProcess.cpp; sourceTree = SOURCE_ROOT; }; + 9A0960F123634603B15EEA38 /* ConvertUTF.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.c; fileEncoding = 4; name = ConvertUTF.c; path = contrib/ConvertUTF/ConvertUTF.c; sourceTree = SOURCE_ROOT; }; + 9A61AF384D4D45778698DD7D /* ASELoader.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = ASELoader.h; path = code/ASELoader.h; sourceTree = SOURCE_ROOT; }; + 9B2827B3E64147E08A5AD334 /* SkeletonMeshBuilder.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = SkeletonMeshBuilder.cpp; path = code/SkeletonMeshBuilder.cpp; sourceTree = SOURCE_ROOT; }; + 9B4221AA0AD2418FAA45EB64 /* FindInvalidDataProcess.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = FindInvalidDataProcess.cpp; path = code/FindInvalidDataProcess.cpp; sourceTree = SOURCE_ROOT; }; + 9C5E3F9248B64C7EBF20EC27 /* Hash.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = Hash.h; path = code/Hash.h; sourceTree = SOURCE_ROOT; }; + 9D203F78B24C4D7E8E2084A3 /* FBXProperties.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = FBXProperties.cpp; path = code/FBXProperties.cpp; sourceTree = SOURCE_ROOT; }; + 9E0572B45F1F4605BD5C919D /* COBScene.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = COBScene.h; path = code/COBScene.h; sourceTree = SOURCE_ROOT; }; + A06CBE89CFAB48E786F7A5C0 /* 3DSLoader.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = 3DSLoader.h; path = code/3DSLoader.h; sourceTree = SOURCE_ROOT; }; + A0AED12A1A6D4635A8CFB65A /* GenVertexNormalsProcess.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = GenVertexNormalsProcess.cpp; path = code/GenVertexNormalsProcess.cpp; sourceTree = SOURCE_ROOT; }; + A14347E954E8413CAF1455EA /* LWOAnimation.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = LWOAnimation.h; path = code/LWOAnimation.h; sourceTree = SOURCE_ROOT; }; + A1A9535EDF9A4FF2B8DABD7D /* AssimpCExport.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = AssimpCExport.cpp; path = code/AssimpCExport.cpp; sourceTree = SOURCE_ROOT; }; + A257229A058041389981CFC1 /* XFileExporter.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = XFileExporter.h; path = code/XFileExporter.h; sourceTree = SOURCE_ROOT; }; + A277DBC1EFB944F995659A20 /* MD5Loader.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = MD5Loader.cpp; path = code/MD5Loader.cpp; sourceTree = SOURCE_ROOT; }; + A3D3024C3A59423487A125C8 /* STEPFileReader.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = STEPFileReader.h; path = code/STEPFileReader.h; sourceTree = SOURCE_ROOT; }; + A43641DC9C1B4B578BC40476 /* SplitLargeMeshes.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = SplitLargeMeshes.cpp; path = code/SplitLargeMeshes.cpp; sourceTree = SOURCE_ROOT; }; + A436C47FBF904FECB4A58462 /* ProcessHelper.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = ProcessHelper.h; path = code/ProcessHelper.h; sourceTree = SOURCE_ROOT; }; + A4CBF9157F01460ABEDEBF28 /* crypt.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = crypt.h; path = contrib/unzip/crypt.h; sourceTree = SOURCE_ROOT; }; + A58410FEAA884A2D8D73ACCE /* BaseImporter.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = BaseImporter.cpp; path = code/BaseImporter.cpp; sourceTree = SOURCE_ROOT; }; + A72115ED828F4069A427B460 /* Subdivision.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = Subdivision.h; path = code/Subdivision.h; sourceTree = SOURCE_ROOT; }; + A7733823362B4A389102D177 /* TargetAnimation.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = TargetAnimation.h; path = code/TargetAnimation.h; sourceTree = SOURCE_ROOT; }; + A7A56A688A3845768410F500 /* FBXConverter.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = FBXConverter.cpp; path = code/FBXConverter.cpp; sourceTree = SOURCE_ROOT; }; + A7A86F81858F4D928A568E17 /* FBXConverter.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = FBXConverter.h; path = code/FBXConverter.h; sourceTree = SOURCE_ROOT; }; + A7A990C6FF244DC397B7BA7C /* MS3DLoader.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = MS3DLoader.cpp; path = code/MS3DLoader.cpp; sourceTree = SOURCE_ROOT; }; + A7CEBC6894424B888326CAB2 /* tuple.hpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; name = tuple.hpp; path = code/BoostWorkaround/boost/tuple/tuple.hpp; sourceTree = SOURCE_ROOT; }; + A88D56FBEA084A3EA9A0ECB3 /* Q3BSPFileImporter.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = Q3BSPFileImporter.cpp; path = code/Q3BSPFileImporter.cpp; sourceTree = SOURCE_ROOT; }; + A9E9EB834E09420197C3FB8C /* DefaultLogger.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = DefaultLogger.cpp; path = code/DefaultLogger.cpp; sourceTree = SOURCE_ROOT; }; + AA4946AEDB9F4F22873C4C4F /* FBXImporter.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = FBXImporter.h; path = code/FBXImporter.h; sourceTree = SOURCE_ROOT; }; + AA92FFC8B06D4569AD9C4CB1 /* MDLLoader.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = MDLLoader.cpp; path = code/MDLLoader.cpp; sourceTree = SOURCE_ROOT; }; + AAB9AE5328F843F5A8A3E85C /* OptimizeGraph.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = OptimizeGraph.cpp; path = code/OptimizeGraph.cpp; sourceTree = SOURCE_ROOT; }; + AAD3EA9B0BB84A788FCCA83E /* foreach.hpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; name = foreach.hpp; path = code/BoostWorkaround/boost/foreach.hpp; sourceTree = SOURCE_ROOT; }; + ABDA70358E34432A8A4637F4 /* RemoveVCProcess.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = RemoveVCProcess.h; path = code/RemoveVCProcess.h; sourceTree = SOURCE_ROOT; }; + AC699876B6364EC1878CBA44 /* OgreXmlSerializer.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = OgreXmlSerializer.h; path = code/OgreXmlSerializer.h; sourceTree = SOURCE_ROOT; }; + ACF73EEAB2424213BF7158D5 /* ObjFileParser.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = ObjFileParser.cpp; path = code/ObjFileParser.cpp; sourceTree = SOURCE_ROOT; }; + AD969BA482564C7FAA372F7C /* RemoveRedundantMaterials.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = RemoveRedundantMaterials.h; path = code/RemoveRedundantMaterials.h; sourceTree = SOURCE_ROOT; }; + ADACEBC4973F4FC0A6FEC68A /* RemoveRedundantMaterials.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = RemoveRedundantMaterials.cpp; path = code/RemoveRedundantMaterials.cpp; sourceTree = SOURCE_ROOT; }; + AE00939F150F413780C8AAD7 /* shapes.cc */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = shapes.cc; path = contrib/poly2tri/poly2tri/common/shapes.cc; sourceTree = SOURCE_ROOT; }; + AE1C2E2C9C424B3684AD9D4A /* texture.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = texture.h; path = include/assimp/texture.h; sourceTree = SOURCE_ROOT; }; + AF75E6049338489BB256D295 /* ioapi.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.c; fileEncoding = 4; name = ioapi.c; path = contrib/unzip/ioapi.c; sourceTree = SOURCE_ROOT; }; + AFA8B6DE5B3A4E52A85041C9 /* LWOFileData.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = LWOFileData.h; path = code/LWOFileData.h; sourceTree = SOURCE_ROOT; }; + AFF41974881F466A9561BE4B /* LWSLoader.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = LWSLoader.cpp; path = code/LWSLoader.cpp; sourceTree = SOURCE_ROOT; }; + B04FE3598E344EC09B59CA2F /* IRRShared.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = IRRShared.h; path = code/IRRShared.h; sourceTree = SOURCE_ROOT; }; + B05DC38593F04180B322360B /* camera.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = camera.h; path = include/assimp/camera.h; sourceTree = SOURCE_ROOT; }; + B211101B342C414A9E43B7BC /* SplitByBoneCountProcess.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = SplitByBoneCountProcess.h; path = code/SplitByBoneCountProcess.h; sourceTree = SOURCE_ROOT; }; + B36DA471B9E142FC9425EC45 /* JoinVerticesProcess.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = JoinVerticesProcess.cpp; path = code/JoinVerticesProcess.cpp; sourceTree = SOURCE_ROOT; }; + B3E8A1BEF8E74F04AE06871B /* AssxmlExporter.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = AssxmlExporter.cpp; path = code/AssxmlExporter.cpp; sourceTree = SOURCE_ROOT; }; + B4086213AE40445F817FA840 /* RemoveComments.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = RemoveComments.h; path = code/RemoveComments.h; sourceTree = SOURCE_ROOT; }; + B40FE1BF9D8E411493BBDE0C /* ComputeUVMappingProcess.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = ComputeUVMappingProcess.h; path = code/ComputeUVMappingProcess.h; sourceTree = SOURCE_ROOT; }; + B441D87EE6ED4EBFB0586B66 /* anim.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = anim.h; path = include/assimp/anim.h; sourceTree = SOURCE_ROOT; }; + B4C688FA08F44716855CDD3C /* FBXImporter.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = FBXImporter.cpp; path = code/FBXImporter.cpp; sourceTree = SOURCE_ROOT; }; + B4F1B5789CA540C78FB9219D /* NDOLoader.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = NDOLoader.cpp; path = code/NDOLoader.cpp; sourceTree = SOURCE_ROOT; }; + B522B83A39CA461CBCABE25A /* BlenderScene.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = BlenderScene.h; path = code/BlenderScene.h; sourceTree = SOURCE_ROOT; }; + B54FBAAF061B40DBA3F48F83 /* IOStream.hpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; name = IOStream.hpp; path = include/assimp/IOStream.hpp; sourceTree = SOURCE_ROOT; }; + B6074B1E864740F787A97EA3 /* vector2.inl */ = {isa = PBXFileReference; explicitFileType = sourcecode; fileEncoding = 4; name = vector2.inl; path = include/assimp/vector2.inl; sourceTree = SOURCE_ROOT; }; + B65258E349704523BC43904D /* BlenderDNA.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = BlenderDNA.cpp; path = code/BlenderDNA.cpp; sourceTree = SOURCE_ROOT; }; + B6982D8069A145E5B9F97684 /* DXFHelper.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = DXFHelper.h; path = code/DXFHelper.h; sourceTree = SOURCE_ROOT; }; + B7192C50B16142398B7CD221 /* DefaultProgressHandler.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = DefaultProgressHandler.h; path = code/DefaultProgressHandler.h; sourceTree = SOURCE_ROOT; }; + B72D0BA3EF66439F8D582ED3 /* advancing_front.cc */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = advancing_front.cc; path = contrib/poly2tri/poly2tri/sweep/advancing_front.cc; sourceTree = SOURCE_ROOT; }; + B9DFF24FD63A4D9FAE213EED /* Importer.hpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; name = Importer.hpp; path = include/assimp/Importer.hpp; sourceTree = SOURCE_ROOT; }; + BA832069DF214327AE067503 /* matrix4x4.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = matrix4x4.h; path = include/assimp/matrix4x4.h; sourceTree = SOURCE_ROOT; }; + BABB7734139C452A9DDEE797 /* FindDegenerates.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = FindDegenerates.cpp; path = code/FindDegenerates.cpp; sourceTree = SOURCE_ROOT; }; + BB38E7E7661842448F008372 /* FBXDocumentUtil.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = FBXDocumentUtil.cpp; path = code/FBXDocumentUtil.cpp; sourceTree = SOURCE_ROOT; }; + BBEE1CF81183473C8492FC03 /* CalcTangentsProcess.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = CalcTangentsProcess.h; path = code/CalcTangentsProcess.h; sourceTree = SOURCE_ROOT; }; + BD9A81E0E27E44718609615B /* SortByPTypeProcess.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = SortByPTypeProcess.cpp; path = code/SortByPTypeProcess.cpp; sourceTree = SOURCE_ROOT; }; + BDD30C77BB68497EA3B7F2F7 /* StringComparison.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = StringComparison.h; path = code/StringComparison.h; sourceTree = SOURCE_ROOT; }; + BF94F50C216B45388CDEC1EF /* OFFLoader.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = OFFLoader.h; path = code/OFFLoader.h; sourceTree = SOURCE_ROOT; }; + C16ECC01B4954B07AB547D6C /* AssimpPCH.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = AssimpPCH.cpp; path = code/AssimpPCH.cpp; sourceTree = SOURCE_ROOT; }; + C17C5037C995420C8D259C0C /* FBXImportSettings.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = FBXImportSettings.h; path = code/FBXImportSettings.h; sourceTree = SOURCE_ROOT; }; + C18C5023460E4D17B8C922D7 /* StandardShapes.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = StandardShapes.cpp; path = code/StandardShapes.cpp; sourceTree = SOURCE_ROOT; }; + C2C9EAC9B5B74AC397B070E8 /* scoped_array.hpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; name = scoped_array.hpp; path = code/BoostWorkaround/boost/scoped_array.hpp; sourceTree = SOURCE_ROOT; }; + C490BBF1881240EEA4A96315 /* clipper.hpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; name = clipper.hpp; path = contrib/clipper/clipper.hpp; sourceTree = SOURCE_ROOT; }; + C5178B3983F147F3B9BD8217 /* Q3DLoader.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = Q3DLoader.cpp; path = code/Q3DLoader.cpp; sourceTree = SOURCE_ROOT; }; + C54518F708BA4A328D5D7325 /* FixNormalsStep.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = FixNormalsStep.cpp; path = code/FixNormalsStep.cpp; sourceTree = SOURCE_ROOT; }; + C582480917FF4EB09C164D70 /* SMDLoader.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = SMDLoader.h; path = code/SMDLoader.h; sourceTree = SOURCE_ROOT; }; + C5C3ED2BE50D4684994BD533 /* TextureTransform.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = TextureTransform.h; path = code/TextureTransform.h; sourceTree = SOURCE_ROOT; }; + C6D3C3E2BA2F49F2B17E7580 /* STLLoader.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = STLLoader.h; path = code/STLLoader.h; sourceTree = SOURCE_ROOT; }; + C7B37CA474DF4CE7A5B0658E /* ai_assert.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = ai_assert.h; path = include/assimp/ai_assert.h; sourceTree = SOURCE_ROOT; }; + C80B9A3AF4204AE08AA50BAE /* BVHLoader.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = BVHLoader.cpp; path = code/BVHLoader.cpp; sourceTree = SOURCE_ROOT; }; + C84DA0E6CE13493D833BA1C1 /* COBLoader.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = COBLoader.cpp; path = code/COBLoader.cpp; sourceTree = SOURCE_ROOT; }; + C9A101D1311C4E77AAEDD94C /* FindInstancesProcess.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = FindInstancesProcess.cpp; path = code/FindInstancesProcess.cpp; sourceTree = SOURCE_ROOT; }; + CB042D863BD447FFB117AE34 /* 3DSHelper.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = 3DSHelper.h; path = code/3DSHelper.h; sourceTree = SOURCE_ROOT; }; + CC54A231FF6B4B0CABCFD167 /* IRRShared.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = IRRShared.cpp; path = code/IRRShared.cpp; sourceTree = SOURCE_ROOT; }; + CC5D5CA1789448E9869B9669 /* PlyExporter.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = PlyExporter.h; path = code/PlyExporter.h; sourceTree = SOURCE_ROOT; }; + CDE3ECA98173418A9F997992 /* STEPFileReader.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = STEPFileReader.cpp; path = code/STEPFileReader.cpp; sourceTree = SOURCE_ROOT; }; + CEC69808E1844C23B95D3475 /* MDLMaterialLoader.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = MDLMaterialLoader.cpp; path = code/MDLMaterialLoader.cpp; sourceTree = SOURCE_ROOT; }; + CF07D05DC86F4C98BC42FDCF /* FBXTokenizer.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = FBXTokenizer.cpp; path = code/FBXTokenizer.cpp; sourceTree = SOURCE_ROOT; }; + D029CE902F8045B0B3AFFDDB /* ImporterRegistry.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = ImporterRegistry.cpp; path = code/ImporterRegistry.cpp; sourceTree = SOURCE_ROOT; }; + D0E9BB0220704C5D93CE7CE9 /* IFCLoader.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = IFCLoader.cpp; path = code/IFCLoader.cpp; sourceTree = SOURCE_ROOT; }; + D1073FF20359469D921C9316 /* irrXMLWrapper.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = irrXMLWrapper.h; path = code/irrXMLWrapper.h; sourceTree = SOURCE_ROOT; }; + D2869C6AD4814588A45E8F81 /* NFFLoader.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = NFFLoader.h; path = code/NFFLoader.h; sourceTree = SOURCE_ROOT; }; + D2EEB62ECBF749AA89146C66 /* SplitLargeMeshes.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = SplitLargeMeshes.h; path = code/SplitLargeMeshes.h; sourceTree = SOURCE_ROOT; }; + D40F70AC841D4B788B5C696B /* CXMLReaderImpl.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = CXMLReaderImpl.h; path = contrib/irrXML/CXMLReaderImpl.h; sourceTree = SOURCE_ROOT; }; + D56A4C70F65D4E07BD792D2C /* STEPFileEncoding.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = STEPFileEncoding.h; path = code/STEPFileEncoding.h; sourceTree = SOURCE_ROOT; }; + D5F4108F03D7457EB641836B /* MDLFileData.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = MDLFileData.h; path = code/MDLFileData.h; sourceTree = SOURCE_ROOT; }; + D629F6BF53864979B7619067 /* LWOBLoader.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = LWOBLoader.cpp; path = code/LWOBLoader.cpp; sourceTree = SOURCE_ROOT; }; + D82B5BA87B184532BE74D24F /* LogAux.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = LogAux.h; path = code/LogAux.h; sourceTree = SOURCE_ROOT; }; + D958B0B445E64F4BA9145D82 /* DefaultLogger.hpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; name = DefaultLogger.hpp; path = include/assimp/DefaultLogger.hpp; sourceTree = SOURCE_ROOT; }; + D9AB66BD27E246A18091626F /* DefaultIOSystem.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = DefaultIOSystem.h; path = code/DefaultIOSystem.h; sourceTree = SOURCE_ROOT; }; + D9FEEF58B24548F782A5D53C /* AssbinLoader.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = AssbinLoader.cpp; path = code/AssbinLoader.cpp; sourceTree = SOURCE_ROOT; }; + DAE82F651F9E4D91A6A6C753 /* advancing_front.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = advancing_front.h; path = contrib/poly2tri/poly2tri/sweep/advancing_front.h; sourceTree = SOURCE_ROOT; }; + DC0210D3F25F470C86F914B3 /* ColladaParser.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = ColladaParser.h; path = code/ColladaParser.h; sourceTree = SOURCE_ROOT; }; + DC67FF8B4313494F8C03D840 /* XMLTools.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = XMLTools.h; path = code/XMLTools.h; sourceTree = SOURCE_ROOT; }; + DD3D18BC2E58447D9879CB00 /* OptimizeMeshes.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = OptimizeMeshes.h; path = code/OptimizeMeshes.h; sourceTree = SOURCE_ROOT; }; + DD4E4641B0FE4369BF3775C3 /* MDCNormalTable.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = MDCNormalTable.h; path = code/MDCNormalTable.h; sourceTree = SOURCE_ROOT; }; + DD7FFD53046F4AEB898C0832 /* IRRMeshLoader.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = IRRMeshLoader.cpp; path = code/IRRMeshLoader.cpp; sourceTree = SOURCE_ROOT; }; + DDDE82BDF4F94E0EA35649A4 /* LimitBoneWeightsProcess.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = LimitBoneWeightsProcess.h; path = code/LimitBoneWeightsProcess.h; sourceTree = SOURCE_ROOT; }; + DE0D259917354C80BE1CC791 /* BlenderScene.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = BlenderScene.cpp; path = code/BlenderScene.cpp; sourceTree = SOURCE_ROOT; }; + DE811A81663A492A84E13937 /* ObjExporter.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = ObjExporter.cpp; path = code/ObjExporter.cpp; sourceTree = SOURCE_ROOT; }; + DF76D04D95E649BCBC15E64F /* TextureTransform.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = TextureTransform.cpp; path = code/TextureTransform.cpp; sourceTree = SOURCE_ROOT; }; + DFF8AF202CAA40E69D1A2BD0 /* static_assert.hpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; name = static_assert.hpp; path = code/BoostWorkaround/boost/static_assert.hpp; sourceTree = SOURCE_ROOT; }; + E01801CB159D47928B3D96B5 /* TinyFormatter.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = TinyFormatter.h; path = code/TinyFormatter.h; sourceTree = SOURCE_ROOT; }; + E065DB38B0284196A9283CA3 /* LimitBoneWeightsProcess.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = LimitBoneWeightsProcess.cpp; path = code/LimitBoneWeightsProcess.cpp; sourceTree = SOURCE_ROOT; }; + E11A39E91576445599DF2AC4 /* STEPFileEncoding.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = STEPFileEncoding.cpp; path = code/STEPFileEncoding.cpp; sourceTree = SOURCE_ROOT; }; + E1313C36045444619026E9FB /* cfileio.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = cfileio.h; path = include/assimp/cfileio.h; sourceTree = SOURCE_ROOT; }; + E24E950227C848D3A759F5C2 /* MDLLoader.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = MDLLoader.h; path = code/MDLLoader.h; sourceTree = SOURCE_ROOT; }; + E51043448F1744FFA78526D5 /* PlyExporter.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = PlyExporter.cpp; path = code/PlyExporter.cpp; sourceTree = SOURCE_ROOT; }; + E6332CD992D447CA910DA456 /* FBXUtil.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = FBXUtil.cpp; path = code/FBXUtil.cpp; sourceTree = SOURCE_ROOT; }; + E663847651834244834CB9F5 /* PostStepRegistry.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = PostStepRegistry.cpp; path = code/PostStepRegistry.cpp; sourceTree = SOURCE_ROOT; }; + E7E85BF696E74CFAAEBF895C /* FBXTokenizer.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = FBXTokenizer.h; path = code/FBXTokenizer.h; sourceTree = SOURCE_ROOT; }; + E81BAB0ED0854DDFA62CB956 /* pushpack1.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = pushpack1.h; path = include/assimp/Compiler/pushpack1.h; sourceTree = SOURCE_ROOT; }; + E9ED3048A21E483F9C2721F4 /* mesh.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = mesh.h; path = include/assimp/mesh.h; sourceTree = SOURCE_ROOT; }; + EAD338BE19AE4C2E897B38B6 /* RawLoader.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = RawLoader.h; path = code/RawLoader.h; sourceTree = SOURCE_ROOT; }; + EAD34F1AA6664B6B935C9421 /* FBXAnimation.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = FBXAnimation.cpp; path = code/FBXAnimation.cpp; sourceTree = SOURCE_ROOT; }; + ECCBBF2D75A44335AB93C84A /* 3DSExporter.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = 3DSExporter.cpp; path = code/3DSExporter.cpp; sourceTree = SOURCE_ROOT; }; + ED20428B31DF46C6A9D65322 /* StreamReader.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = StreamReader.h; path = code/StreamReader.h; sourceTree = SOURCE_ROOT; }; + EE545B58FA1246C792C6AD01 /* shapes.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = shapes.h; path = contrib/poly2tri/poly2tri/common/shapes.h; sourceTree = SOURCE_ROOT; }; + EE6163EB035149A6B8139DB8 /* FBXMaterial.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = FBXMaterial.cpp; path = code/FBXMaterial.cpp; sourceTree = SOURCE_ROOT; }; + EF9F805A4BA4428CA98C9DE5 /* OgreXmlSerializer.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = OgreXmlSerializer.cpp; path = code/OgreXmlSerializer.cpp; sourceTree = SOURCE_ROOT; }; + EFD557FE2C3A46D78F070655 /* OFFLoader.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = OFFLoader.cpp; path = code/OFFLoader.cpp; sourceTree = SOURCE_ROOT; }; + F1076BAC69DB4935A93045A8 /* ACLoader.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = ACLoader.cpp; path = code/ACLoader.cpp; sourceTree = SOURCE_ROOT; }; + F1A7BD0B5CAE48699FCAEBD1 /* MDLDefaultColorMap.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = MDLDefaultColorMap.h; path = code/MDLDefaultColorMap.h; sourceTree = SOURCE_ROOT; }; + F22D5BA425444A028DA42BEA /* FBXDocument.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = FBXDocument.cpp; path = code/FBXDocument.cpp; sourceTree = SOURCE_ROOT; }; + F44E3625C31843B0AFA1A744 /* AssxmlExporter.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = AssxmlExporter.h; path = code/AssxmlExporter.h; sourceTree = SOURCE_ROOT; }; + F468200042534D7CA2C9D891 /* BaseProcess.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = BaseProcess.h; path = code/BaseProcess.h; sourceTree = SOURCE_ROOT; }; + F4AE5F74C20B400EA688B5ED /* VertexTriangleAdjacency.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = VertexTriangleAdjacency.h; path = code/VertexTriangleAdjacency.h; sourceTree = SOURCE_ROOT; }; + F4BA09C943DD49E184316D97 /* Win32DebugLogStream.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = Win32DebugLogStream.h; path = code/Win32DebugLogStream.h; sourceTree = SOURCE_ROOT; }; + F5720C42345840CB9FEA5A40 /* BlenderModifier.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = BlenderModifier.h; path = code/BlenderModifier.h; sourceTree = SOURCE_ROOT; }; + F75457C6D026451B9267B65E /* OgreMaterial.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = OgreMaterial.cpp; path = code/OgreMaterial.cpp; sourceTree = SOURCE_ROOT; }; + F81AE18E4AA94F9597FCB040 /* Importer.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = Importer.h; path = code/Importer.h; sourceTree = SOURCE_ROOT; }; + F898EEA0D9E64425A790587D /* Q3BSPFileImporter.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = Q3BSPFileImporter.h; path = code/Q3BSPFileImporter.h; sourceTree = SOURCE_ROOT; }; + F8AC3A243B9C47D6B31348BA /* FBXParser.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = FBXParser.h; path = code/FBXParser.h; sourceTree = SOURCE_ROOT; }; + F8B1133805564E18B32FFA83 /* OgreStructs.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = OgreStructs.h; path = code/OgreStructs.h; sourceTree = SOURCE_ROOT; }; + F9FEF4D69EFC4605A4F752E5 /* DefaultIOStream.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = DefaultIOStream.cpp; path = code/DefaultIOStream.cpp; sourceTree = SOURCE_ROOT; }; + FAB6BC13FCFE40F5801D0972 /* BaseProcess.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = BaseProcess.cpp; path = code/BaseProcess.cpp; sourceTree = SOURCE_ROOT; }; + FAC67CC462484F92A2CBD7D3 /* poppack1.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = poppack1.h; path = include/assimp/Compiler/poppack1.h; sourceTree = SOURCE_ROOT; }; + FB1E84BE85A34F98A44BBB2B /* vector2.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = vector2.h; path = include/assimp/vector2.h; sourceTree = SOURCE_ROOT; }; + FB2510D46F504365A03EE8A8 /* TriangulateProcess.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = TriangulateProcess.h; path = code/TriangulateProcess.h; sourceTree = SOURCE_ROOT; }; + FB4ABA17AF264257BDA4D921 /* RemoveVCProcess.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = RemoveVCProcess.cpp; path = code/RemoveVCProcess.cpp; sourceTree = SOURCE_ROOT; }; + FB55283BC24C4A1CA86C4900 /* PolyTools.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = PolyTools.h; path = code/PolyTools.h; sourceTree = SOURCE_ROOT; }; + FBC2BA7F2269489694BC890D /* FBXProperties.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = FBXProperties.h; path = code/FBXProperties.h; sourceTree = SOURCE_ROOT; }; + FC0801BA1F95494498A089AF /* version.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = version.h; path = include/assimp/version.h; sourceTree = SOURCE_ROOT; }; + FCCB4BB481FB461688FE2F29 /* B3DImporter.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = B3DImporter.cpp; path = code/B3DImporter.cpp; sourceTree = SOURCE_ROOT; }; + FD84CFD1BD3E4AF4BA622BB8 /* MD2NormalTable.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = MD2NormalTable.h; path = code/MD2NormalTable.h; sourceTree = SOURCE_ROOT; }; + FD9BEC6B8A264AB092F98E20 /* SMDLoader.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = SMDLoader.cpp; path = code/SMDLoader.cpp; sourceTree = SOURCE_ROOT; }; + FEEA39CDD7934999B89E2B4D /* MaterialSystem.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = MaterialSystem.h; path = code/MaterialSystem.h; sourceTree = SOURCE_ROOT; }; + FF4E90FB1A3446F095ECC8BD /* Exporter.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = Exporter.cpp; path = code/Exporter.cpp; sourceTree = SOURCE_ROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXGroup section */ + 0117589D2B25420F831BA4CE /* MS3D */ = { + isa = PBXGroup; + children = ( + A7A990C6FF244DC397B7BA7C /* MS3DLoader.cpp */, + 6347FA5D391D4320B9457D3F /* MS3DLoader.h */, + ); + name = MS3D; + sourceTree = ""; + }; + 0593669570C8417B8FE0C89E /* Obj */ = { + isa = PBXGroup; + children = ( + DE811A81663A492A84E13937 /* ObjExporter.cpp */, + 91EF6411C40946758A06144F /* ObjExporter.h */, + 005DFE3B6FFC4BEBB7055330 /* ObjFileData.h */, + 862131D4574B4CABA5EC957B /* ObjFileImporter.cpp */, + 1FC965B1F11B45F98051C565 /* ObjFileImporter.h */, + 4108529663904025B21E526B /* ObjFileMtlImporter.cpp */, + 180177D50FDA4C10AD629DC2 /* ObjFileMtlImporter.h */, + ACF73EEAB2424213BF7158D5 /* ObjFileParser.cpp */, + 333F4676A92043739F5A9D32 /* ObjFileParser.h */, + 8FE8B4781BB3406EB3452154 /* ObjTools.h */, + ); + name = Obj; + sourceTree = ""; + }; + 09D1759329AB410E92DC273A /* Collada */ = { + isa = PBXGroup; + children = ( + 1C0527629078403F81CFD117 /* ColladaExporter.cpp */, + 638B3F6AC17A435C9B86C86C /* ColladaExporter.h */, + 7C10178C0B7241DD874A0AF3 /* ColladaHelper.h */, + 1A4706D216414D4F8AA72EC9 /* ColladaLoader.cpp */, + 6981B16018CF46CAA54C0BAA /* ColladaLoader.h */, + 420D77ED33554D54AA4D50EF /* ColladaParser.cpp */, + DC0210D3F25F470C86F914B3 /* ColladaParser.h */, + ); + name = Collada; + sourceTree = ""; + }; + 0C22F81E750C429183194A1D /* Assxml */ = { + isa = PBXGroup; + children = ( + B3E8A1BEF8E74F04AE06871B /* AssxmlExporter.cpp */, + F44E3625C31843B0AFA1A744 /* AssxmlExporter.h */, + ); + name = Assxml; + sourceTree = ""; + }; + 1126F68352DC4FD49AC55DD7 /* ConvertUTF */ = { + isa = PBXGroup; + children = ( + 9A0960F123634603B15EEA38 /* ConvertUTF.c */, + 6F88E78E61FC4A01BC30BE85 /* ConvertUTF.h */, + ); + name = ConvertUTF; + sourceTree = ""; + }; + 16ED8F46E8ED44BAB8D7BA1B /* MaterialSystem */ = { + isa = PBXGroup; + children = ( + 7FF72CB6E99E40E19AE0E64C /* MaterialSystem.cpp */, + FEEA39CDD7934999B89E2B4D /* MaterialSystem.h */, + ); + name = MaterialSystem; + sourceTree = ""; + }; + 1AC84A1DBE804A71B13E06C2 /* Clipper */ = { + isa = PBXGroup; + children = ( + 59F8A11A7AED45CC94CEDF28 /* clipper.cpp */, + C490BBF1881240EEA4A96315 /* clipper.hpp */, + ); + name = Clipper; + sourceTree = ""; + }; + 1BF60AA5F4B147508EB44D8C /* Exporter */ = { + isa = PBXGroup; + children = ( + A1A9535EDF9A4FF2B8DABD7D /* AssimpCExport.cpp */, + 23097CBD64E343738B8F22EE /* BlobIOSystem.h */, + FF4E90FB1A3446F095ECC8BD /* Exporter.cpp */, + ); + name = Exporter; + sourceTree = ""; + }; + 2B78DE034A954FAD96DA8432 /* IFC */ = { + isa = PBXGroup; + children = ( + 285D1FDA48EC4DD8933B603E /* IFCBoolean.cpp */, + 2E7FD92FFCF441B0A60FC8B4 /* IFCCurve.cpp */, + 3267EBBA6EEB435F83FF25E4 /* IFCGeometry.cpp */, + D0E9BB0220704C5D93CE7CE9 /* IFCLoader.cpp */, + 2BE34AF1CE0C4767ACE21597 /* IFCLoader.h */, + 0014AE5E87A74AAA9EF0EC4B /* IFCMaterial.cpp */, + 74679D2078FD46ED9AC73355 /* IFCOpenings.cpp */, + 46E9F455A3284DB399986293 /* IFCProfile.cpp */, + 3F5D1E6368384D429BA29D5A /* IFCReaderGen.cpp */, + 6162B57DE81A4E538430056E /* IFCReaderGen.h */, + 59E3D32E3FC7438DB148537F /* IFCUtil.cpp */, + 13BFADA520C04B15AE256CC2 /* IFCUtil.h */, + 47FF3063906E4786ABF0939B /* STEPFile.h */, + E11A39E91576445599DF2AC4 /* STEPFileEncoding.cpp */, + D56A4C70F65D4E07BD792D2C /* STEPFileEncoding.h */, + CDE3ECA98173418A9F997992 /* STEPFileReader.cpp */, + A3D3024C3A59423487A125C8 /* STEPFileReader.h */, + ); + name = IFC; + sourceTree = ""; + }; + 2CA4999D40FC406B97E1FFD3 /* Compiler */ = { + isa = PBXGroup; + children = ( + FAC67CC462484F92A2CBD7D3 /* poppack1.h */, + 278FB5C8BD814F2DAE04A1C7 /* pstdint.h */, + E81BAB0ED0854DDFA62CB956 /* pushpack1.h */, + ); + name = Compiler; + sourceTree = ""; + }; + 2DC7AE369B84444B9649035D /* assimp */ = { + isa = PBXGroup; + children = ( + DB181885BFCC44F594A1FA01 /* Source Files */, + 628C9A9A9FA640B9AA1DAC09 /* Common */, + 874C614E5BEB41419F0EEE1C /* Logging */, + 1BF60AA5F4B147508EB44D8C /* Exporter */, + D3013C8FC8034BC6859BC020 /* PostProcessing */, + 9AC9FD0CD777436C9C7291FF /* 3DS */, + 98D9A21F310D47DD8F390780 /* AC */, + CB3420FADCED418CACDBB584 /* ASE */, + A7F45F8E82C445EBA7D67C36 /* Assbin */, + 0C22F81E750C429183194A1D /* Assxml */, + A1E04517F0D440CDB46985A7 /* B3D */, + 91C8DA33C37E491BBAD264C5 /* BVH */, + 09D1759329AB410E92DC273A /* Collada */, + 5F3147F7FF1044D49A824DBC /* DXF */, + DD5B35196B184EFB820D1FBB /* CSM */, + 723B9CB1C871444FBB302576 /* HMP */, + 6CB3C1AECE8A4745861D913D /* Irr */, + 873AA0EB80814B0A9461BB7E /* LWO */, + 32F48CB0DF784B6BA63A5025 /* LWS */, + F9261D592F00437EAFC663B5 /* MD2 */, + 7D3FF9CAC50E41F0B59B9758 /* MD3 */, + 97326C49E0E34D43AE80F0FF /* MD5 */, + CB981D90CEF4472191978170 /* MDC */, + EF7D37EB84AF45FC8BF47E7F /* MDL */, + 16ED8F46E8ED44BAB8D7BA1B /* MaterialSystem */, + CF7D1A0DBB134AC4BCFE3C3F /* NFF */, + 8438F0F891674542AF8F2302 /* OFFFormat */, + 0593669570C8417B8FE0C89E /* Obj */, + 6D12DDA749D645C68DBED62E /* Ogre */, + 462ED039D874460E97B08346 /* Ply */, + F0273EDFDBD34EDAA6678613 /* Q3D */, + C3D412701D614559B698CED1 /* Q3BSP */, + 9A8E68D1ECFC49B9BB435F1C /* Raw */, + 8C2B1B7516DD4C4798F5048F /* SMD */, + 2E29D94CA6DA405EB4AF90E0 /* STL */, + 3A5EB041B5CD4F98802B2540 /* Terragen */, + 8565C30231D64E81BB2B4ECD /* Unreal */, + 96A36CD42ADB4BBBB54004E1 /* XFile */, + 6E21649785DD4DB08D9A505D /* Extra */, + 0117589D2B25420F831BA4CE /* MS3D */, + DAFF6641A88441AFBE8B99B1 /* COB */, + 71D6A260C79746D3B50849D2 /* BLENDER */, + 71199EE27B264D74B9D0A1C2 /* NDO */, + 2B78DE034A954FAD96DA8432 /* IFC */, + 2FC31A6272B94FB681FB8087 /* XGL */, + 7F21D60E8DCD4C65923BD76C /* FBX */, + 6B385D1E46704FB7BABB2D90 /* IrrXML */, + 1126F68352DC4FD49AC55DD7 /* ConvertUTF */, + 8B032622745B45FDB154A53C /* unzip */, + F61A479614764D11AC3311A8 /* Poly2Tri */, + 1AC84A1DBE804A71B13E06C2 /* Clipper */, + 3B11CB13DD484F938D3E3792 /* Boost */, + FCFE51BCE7384933A972EDEE /* Header Files */, + 2CA4999D40FC406B97E1FFD3 /* Compiler */, + ); + name = assimp; + sourceTree = ""; + }; + 2E29D94CA6DA405EB4AF90E0 /* STL */ = { + isa = PBXGroup; + children = ( + 89D2D359BD854D8AA60CB720 /* STLExporter.cpp */, + 88ADA502481B403191BD35F0 /* STLExporter.h */, + 4D2F1605B9484B08BB33402D /* STLLoader.cpp */, + C6D3C3E2BA2F49F2B17E7580 /* STLLoader.h */, + ); + name = STL; + sourceTree = ""; + }; + 2FC31A6272B94FB681FB8087 /* XGL */ = { + isa = PBXGroup; + children = ( + 8E395349546A4FDF843E6963 /* XGLLoader.cpp */, + 501B18C2B590455D8A3C3E78 /* XGLLoader.h */, + ); + name = XGL; + sourceTree = ""; + }; + 32F48CB0DF784B6BA63A5025 /* LWS */ = { + isa = PBXGroup; + children = ( + AFF41974881F466A9561BE4B /* LWSLoader.cpp */, + 68703F99581F49CB9E2B9F37 /* LWSLoader.h */, + ); + name = LWS; + sourceTree = ""; + }; + 3A5EB041B5CD4F98802B2540 /* Terragen */ = { + isa = PBXGroup; + children = ( + 4866DA5A7BFD49F79B61CBF8 /* TerragenLoader.cpp */, + 815702BED5644DD5B242F347 /* TerragenLoader.h */, + ); + name = Terragen; + sourceTree = ""; + }; + 3B11CB13DD484F938D3E3792 /* Boost */ = { + isa = PBXGroup; + children = ( + AAD3EA9B0BB84A788FCCA83E /* foreach.hpp */, + 1DC56C794E434BA28E5CCC36 /* format.hpp */, + 96A02CBA1AE642BD9519719D /* make_shared.hpp */, + 967D69AC1A344D4E988F0B2C /* common_factor_rt.hpp */, + C2C9EAC9B5B74AC397B070E8 /* scoped_array.hpp */, + 7644CE6B26D740258577EE9D /* scoped_ptr.hpp */, + 8C9AEFFFF3B948148D32D76F /* shared_array.hpp */, + 3E84DEFC1E0646AD82F79998 /* shared_ptr.hpp */, + DFF8AF202CAA40E69D1A2BD0 /* static_assert.hpp */, + A7CEBC6894424B888326CAB2 /* tuple.hpp */, + ); + name = Boost; + sourceTree = ""; + }; + 462ED039D874460E97B08346 /* Ply */ = { + isa = PBXGroup; + children = ( + E51043448F1744FFA78526D5 /* PlyExporter.cpp */, + CC5D5CA1789448E9869B9669 /* PlyExporter.h */, + 409C98EE093C499B8A574CA9 /* PlyLoader.cpp */, + 91D49B3C51684882A01EA492 /* PlyLoader.h */, + 2C4D504725E540109530E254 /* PlyParser.cpp */, + 45F6A2B351AB4B749E55B299 /* PlyParser.h */, + ); + name = Ply; + sourceTree = ""; + }; + 5F3147F7FF1044D49A824DBC /* DXF */ = { + isa = PBXGroup; + children = ( + B6982D8069A145E5B9F97684 /* DXFHelper.h */, + 466D6B9A7CCD402D9AA87071 /* DXFLoader.cpp */, + 7BDF90B124F74A39A5EB3B02 /* DXFLoader.h */, + ); + name = DXF; + sourceTree = ""; + }; + 628C9A9A9FA640B9AA1DAC09 /* Common */ = { + isa = PBXGroup; + children = ( + A58410FEAA884A2D8D73ACCE /* BaseImporter.cpp */, + 32170F499DAC4E4595AF6D6B /* BaseImporter.h */, + FAB6BC13FCFE40F5801D0972 /* BaseProcess.cpp */, + F468200042534D7CA2C9D891 /* BaseProcess.h */, + 10238FBD7A9D401A82D667CB /* Bitmap.cpp */, + 49AFF879142C4BA4865843DC /* Bitmap.h */, + 22E66A720E694DAF9469EB92 /* ByteSwap.h */, + 339E56B5FD264481BBF21835 /* CInterfaceIOWrapper.h */, + F9FEF4D69EFC4605A4F752E5 /* DefaultIOStream.cpp */, + 32CC68350B7640ACA7C83DDA /* DefaultIOStream.h */, + 1D502654EF864101A2DA9476 /* DefaultIOSystem.cpp */, + D9AB66BD27E246A18091626F /* DefaultIOSystem.h */, + B7192C50B16142398B7CD221 /* DefaultProgressHandler.h */, + 3ACFF3FC39C74C4A966C0FEA /* GenericProperty.h */, + 9C5E3F9248B64C7EBF20EC27 /* Hash.h */, + 6AC645CEB6F74AE5A62DF68B /* IFF.h */, + 9472EFB6831740DD91471337 /* Importer.cpp */, + F81AE18E4AA94F9597FCB040 /* Importer.h */, + D029CE902F8045B0B3AFFDDB /* ImporterRegistry.cpp */, + 680FBD79376A41B690C405B8 /* LineSplitter.h */, + D82B5BA87B184532BE74D24F /* LogAux.h */, + 7DC4B0B5E57F4F4892CC823E /* MemoryIOWrapper.h */, + 0C1B00249A554394A4F9CF2A /* ParsingUtils.h */, + E663847651834244834CB9F5 /* PostStepRegistry.cpp */, + 5C1EA03E3AE24AA5A778B7F1 /* Profiler.h */, + 6A86069DEEDC42B88634F78D /* RemoveComments.cpp */, + B4086213AE40445F817FA840 /* RemoveComments.h */, + 52836A0629E24447B924750A /* SGSpatialSort.cpp */, + 8299401C3E4A43A18E887DC1 /* SGSpatialSort.h */, + 73A3D87FF2C04C3BA3684F54 /* SceneCombiner.cpp */, + 8476FEE874C1404B9B4B9617 /* SceneCombiner.h */, + 1775DE08FC8647EB896A0FB3 /* ScenePreprocessor.cpp */, + 4FE1E4726B144AD1B922A1A0 /* ScenePreprocessor.h */, + 97914BDA4AA34081855BF16C /* ScenePrivate.h */, + 9B2827B3E64147E08A5AD334 /* SkeletonMeshBuilder.cpp */, + 45BC2EB74251493CBBFAEB5D /* SkeletonMeshBuilder.h */, + 2DCF6F156A3A4B4C807E5368 /* SmoothingGroups.h */, + 8EEC6646FC044D1E9658A590 /* SpatialSort.cpp */, + 957FBC18FED2484F83308E36 /* SpatialSort.h */, + 99A4349D505F4CC593F48CF6 /* SplitByBoneCountProcess.cpp */, + B211101B342C414A9E43B7BC /* SplitByBoneCountProcess.h */, + C18C5023460E4D17B8C922D7 /* StandardShapes.cpp */, + 296407DE471C4F298742FB59 /* StandardShapes.h */, + ED20428B31DF46C6A9D65322 /* StreamReader.h */, + 7E8BA0D338C9433587BC6C35 /* StreamWriter.h */, + BDD30C77BB68497EA3B7F2F7 /* StringComparison.h */, + 4BBDEB63CFEB4F2EAA95358D /* Subdivision.cpp */, + A72115ED828F4069A427B460 /* Subdivision.h */, + 6F65B6129F774AEDB8DC845A /* TargetAnimation.cpp */, + A7733823362B4A389102D177 /* TargetAnimation.h */, + E01801CB159D47928B3D96B5 /* TinyFormatter.h */, + 1533BE4C09F1430C8BF4D248 /* Vertex.h */, + 0AAF26EBF0A64ABDB840BA64 /* VertexTriangleAdjacency.cpp */, + F4AE5F74C20B400EA688B5ED /* VertexTriangleAdjacency.h */, + DC67FF8B4313494F8C03D840 /* XMLTools.h */, + 1AF1EE8EFE594A40ACE03D19 /* fast_atof.h */, + 262DFE65C6D34442AA79D15A /* qnan.h */, + ); + name = Common; + sourceTree = ""; + }; + 6B385D1E46704FB7BABB2D90 /* IrrXML */ = { + isa = PBXGroup; + children = ( + D1073FF20359469D921C9316 /* irrXMLWrapper.h */, + D40F70AC841D4B788B5C696B /* CXMLReaderImpl.h */, + 02587469A85540EE875B04B5 /* heapsort.h */, + 49FE5C30FC854A3EBD0E9C19 /* irrArray.h */, + 5D4E64EABD9548A59E9637AF /* irrString.h */, + 4936396409984881858E7B15 /* irrTypes.h */, + 64C6BACDA5DD4139AA26EE81 /* irrXML.cpp */, + 12E167EBA81B4CD3A241D7AF /* irrXML.h */, + ); + name = IrrXML; + sourceTree = ""; + }; + 6CB3C1AECE8A4745861D913D /* Irr */ = { + isa = PBXGroup; + children = ( + 97DFA90F9D0C4B999C150B10 /* IRRLoader.cpp */, + 1011FC45108745A7BBA98904 /* IRRLoader.h */, + DD7FFD53046F4AEB898C0832 /* IRRMeshLoader.cpp */, + 670FE6DD7EDF421488F2F97F /* IRRMeshLoader.h */, + CC54A231FF6B4B0CABCFD167 /* IRRShared.cpp */, + B04FE3598E344EC09B59CA2F /* IRRShared.h */, + ); + name = Irr; + sourceTree = ""; + }; + 6D12DDA749D645C68DBED62E /* Ogre */ = { + isa = PBXGroup; + children = ( + 56ADEC4899C047F2839AD791 /* OgreBinarySerializer.cpp */, + 916456789C75419DB1436FAD /* OgreBinarySerializer.h */, + 923283A9791E4B4E86D623FC /* OgreImporter.cpp */, + 71F65BF6936E4E97A5933EF9 /* OgreImporter.h */, + F75457C6D026451B9267B65E /* OgreMaterial.cpp */, + 6F49958B5CCF423681133515 /* OgreParsingUtils.h */, + 79A49EFE23E34E1CBA2E4377 /* OgreStructs.cpp */, + F8B1133805564E18B32FFA83 /* OgreStructs.h */, + EF9F805A4BA4428CA98C9DE5 /* OgreXmlSerializer.cpp */, + AC699876B6364EC1878CBA44 /* OgreXmlSerializer.h */, + ); + name = Ogre; + sourceTree = ""; + }; + 6E21649785DD4DB08D9A505D /* Extra */ = { + isa = PBXGroup; + children = ( + 00EB692107B84590B0560BFB /* MD4FileData.h */, + ); + name = Extra; + sourceTree = ""; + }; + 71199EE27B264D74B9D0A1C2 /* NDO */ = { + isa = PBXGroup; + children = ( + B4F1B5789CA540C78FB9219D /* NDOLoader.cpp */, + 37A3E0E2BB484DD8B9FCCA5E /* NDOLoader.h */, + ); + name = NDO; + sourceTree = ""; + }; + 71D6A260C79746D3B50849D2 /* BLENDER */ = { + isa = PBXGroup; + children = ( + 603AFA882AFF49AEAC2C8FA2 /* BlenderBMesh.cpp */, + 4568875B66584E12AA1538C7 /* BlenderBMesh.h */, + B65258E349704523BC43904D /* BlenderDNA.cpp */, + 72832410F47C44E3BAE709C2 /* BlenderDNA.h */, + 43899EB0B0704A9DB8F0C54F /* BlenderDNA.inl */, + 7CAF8A3096E04CB983B53CC1 /* BlenderIntermediate.h */, + 906F71D342544BF381E1318E /* BlenderLoader.cpp */, + 157C3CC81232428FA535E05F /* BlenderLoader.h */, + 3106D75C13874F5AB3EBBFE7 /* BlenderModifier.cpp */, + F5720C42345840CB9FEA5A40 /* BlenderModifier.h */, + DE0D259917354C80BE1CC791 /* BlenderScene.cpp */, + B522B83A39CA461CBCABE25A /* BlenderScene.h */, + 76D801D898C4443D8240EDB7 /* BlenderSceneGen.h */, + 12C5DD7A285042EDB1897FAE /* BlenderTessellator.cpp */, + 59A1859480754E90B958CA85 /* BlenderTessellator.h */, + ); + name = BLENDER; + sourceTree = ""; + }; + 723B9CB1C871444FBB302576 /* HMP */ = { + isa = PBXGroup; + children = ( + 71EAFDE1910B4A54AAAF2101 /* HMPFileData.h */, + 43ABFF591F374920A5E18A24 /* HMPLoader.cpp */, + 5631CE86F56F458EA0E2415F /* HMPLoader.h */, + 7C63156710964DEDAC0929BD /* HalfLifeFileData.h */, + ); + name = HMP; + sourceTree = ""; + }; + 7D3FF9CAC50E41F0B59B9758 /* MD3 */ = { + isa = PBXGroup; + children = ( + 08E8379F20984AD59515AD95 /* MD3FileData.h */, + 563FBACCFD774BDEA4AEAC10 /* MD3Loader.cpp */, + 1CBCEE37D89145F19F23F036 /* MD3Loader.h */, + ); + name = MD3; + sourceTree = ""; + }; + 7F21D60E8DCD4C65923BD76C /* FBX */ = { + isa = PBXGroup; + children = ( + EAD34F1AA6664B6B935C9421 /* FBXAnimation.cpp */, + 1108AC28566B4D2B9F27C691 /* FBXBinaryTokenizer.cpp */, + 26BF681530B04B73961997CB /* FBXCompileConfig.h */, + A7A56A688A3845768410F500 /* FBXConverter.cpp */, + A7A86F81858F4D928A568E17 /* FBXConverter.h */, + 9855496CEA774F4FA7FBB862 /* FBXDeformer.cpp */, + F22D5BA425444A028DA42BEA /* FBXDocument.cpp */, + 0EF256EC06E345EB930772EC /* FBXDocument.h */, + BB38E7E7661842448F008372 /* FBXDocumentUtil.cpp */, + C17C5037C995420C8D259C0C /* FBXImportSettings.h */, + B4C688FA08F44716855CDD3C /* FBXImporter.cpp */, + AA4946AEDB9F4F22873C4C4F /* FBXImporter.h */, + EE6163EB035149A6B8139DB8 /* FBXMaterial.cpp */, + 42E110B9E6924AF9B55AE65A /* FBXMeshGeometry.cpp */, + 1A61BDC559CE4186B03C0396 /* FBXModel.cpp */, + 33B70115CA54405F895BA471 /* FBXNodeAttribute.cpp */, + 5F373DF3B03B4B848B78EAD2 /* FBXParser.cpp */, + F8AC3A243B9C47D6B31348BA /* FBXParser.h */, + 9D203F78B24C4D7E8E2084A3 /* FBXProperties.cpp */, + FBC2BA7F2269489694BC890D /* FBXProperties.h */, + CF07D05DC86F4C98BC42FDCF /* FBXTokenizer.cpp */, + E7E85BF696E74CFAAEBF895C /* FBXTokenizer.h */, + E6332CD992D447CA910DA456 /* FBXUtil.cpp */, + 89473420F7E448A7BE71FCBA /* FBXUtil.h */, + ); + name = FBX; + sourceTree = ""; + }; + 8438F0F891674542AF8F2302 /* OFFFormat */ = { + isa = PBXGroup; + children = ( + EFD557FE2C3A46D78F070655 /* OFFLoader.cpp */, + BF94F50C216B45388CDEC1EF /* OFFLoader.h */, + ); + name = OFFFormat; + sourceTree = ""; + }; + 8565C30231D64E81BB2B4ECD /* Unreal */ = { + isa = PBXGroup; + children = ( + 3B8FD96D46314ACD8F157AC3 /* UnrealLoader.cpp */, + 27F2019E621B4CDA94DD5270 /* UnrealLoader.h */, + ); + name = Unreal; + sourceTree = ""; + }; + 873AA0EB80814B0A9461BB7E /* LWO */ = { + isa = PBXGroup; + children = ( + 680C392FFE0B4CC5ABC7CA64 /* LWOAnimation.cpp */, + A14347E954E8413CAF1455EA /* LWOAnimation.h */, + D629F6BF53864979B7619067 /* LWOBLoader.cpp */, + AFA8B6DE5B3A4E52A85041C9 /* LWOFileData.h */, + 5A4E05386C094B809A315A07 /* LWOLoader.cpp */, + 72F2DF0B93CF4D3ABAD7513D /* LWOLoader.h */, + 1ED21FC57A384CE6B4F53C0C /* LWOMaterial.cpp */, + ); + name = LWO; + sourceTree = ""; + }; + 874C614E5BEB41419F0EEE1C /* Logging */ = { + isa = PBXGroup; + children = ( + A9E9EB834E09420197C3FB8C /* DefaultLogger.cpp */, + 1520A11AA6E54812939B1FBB /* FileLogStream.h */, + 4CBC1122A79D4F6C94E36CE3 /* StdOStreamLogStream.h */, + F4BA09C943DD49E184316D97 /* Win32DebugLogStream.h */, + D958B0B445E64F4BA9145D82 /* DefaultLogger.hpp */, + 657B9A15EE7A4B7BA519A969 /* LogStream.hpp */, + 56CE07D64D114C4BAB6D9F08 /* Logger.hpp */, + 8D977E197CA4477AB9F3278C /* NullLogger.hpp */, + ); + name = Logging; + sourceTree = ""; + }; + 8B032622745B45FDB154A53C /* unzip */ = { + isa = PBXGroup; + children = ( + A4CBF9157F01460ABEDEBF28 /* crypt.h */, + AF75E6049338489BB256D295 /* ioapi.c */, + 72F637AC7D9E4FBFBB9201CE /* ioapi.h */, + 973D4231A4AA4925B019FEEE /* unzip.c */, + 9293C5A353F9497A850E05D5 /* unzip.h */, + ); + name = unzip; + sourceTree = ""; + }; + 8C2B1B7516DD4C4798F5048F /* SMD */ = { + isa = PBXGroup; + children = ( + FD9BEC6B8A264AB092F98E20 /* SMDLoader.cpp */, + C582480917FF4EB09C164D70 /* SMDLoader.h */, + ); + name = SMD; + sourceTree = ""; + }; + 91C8DA33C37E491BBAD264C5 /* BVH */ = { + isa = PBXGroup; + children = ( + C80B9A3AF4204AE08AA50BAE /* BVHLoader.cpp */, + 45E342A1499E4F03ADD49028 /* BVHLoader.h */, + ); + name = BVH; + sourceTree = ""; + }; + 96A36CD42ADB4BBBB54004E1 /* XFile */ = { + isa = PBXGroup; + children = ( + 435DC362E63D4CCBA68656D3 /* XFileExporter.cpp */, + A257229A058041389981CFC1 /* XFileExporter.h */, + 8F4261792A60481DA04E6E1A /* XFileHelper.h */, + 06DB494DCE4D47FDA00E8B35 /* XFileImporter.cpp */, + 53537D08E9B44A25B43B697B /* XFileImporter.h */, + 74C02A113B804568A7E39CBC /* XFileParser.cpp */, + 3551D90CCED1454A8B912066 /* XFileParser.h */, + ); + name = XFile; + sourceTree = ""; + }; + 97326C49E0E34D43AE80F0FF /* MD5 */ = { + isa = PBXGroup; + children = ( + A277DBC1EFB944F995659A20 /* MD5Loader.cpp */, + 6BAB32C8E06E43689FC5E7EA /* MD5Loader.h */, + 0BC5FD00572F4C58B267A0EC /* MD5Parser.cpp */, + 43FC808D2F4745ACB06A9D33 /* MD5Parser.h */, + ); + name = MD5; + sourceTree = ""; + }; + 98D9A21F310D47DD8F390780 /* AC */ = { + isa = PBXGroup; + children = ( + F1076BAC69DB4935A93045A8 /* ACLoader.cpp */, + 4DABF3CB245F4246B0184513 /* ACLoader.h */, + ); + name = AC; + sourceTree = ""; + }; + 9A8E68D1ECFC49B9BB435F1C /* Raw */ = { + isa = PBXGroup; + children = ( + 1D4A669762194B9D9A26DD20 /* RawLoader.cpp */, + EAD338BE19AE4C2E897B38B6 /* RawLoader.h */, + ); + name = Raw; + sourceTree = ""; + }; + 9AC9FD0CD777436C9C7291FF /* 3DS */ = { + isa = PBXGroup; + children = ( + 15221A74FC9C4B2AAA7306E3 /* 3DSConverter.cpp */, + ECCBBF2D75A44335AB93C84A /* 3DSExporter.cpp */, + 0B519CCAB4B241E59C567077 /* 3DSExporter.h */, + CB042D863BD447FFB117AE34 /* 3DSHelper.h */, + 02E9476D129940BF84DE6682 /* 3DSLoader.cpp */, + A06CBE89CFAB48E786F7A5C0 /* 3DSLoader.h */, + ); + name = 3DS; + sourceTree = ""; + }; + A1E04517F0D440CDB46985A7 /* B3D */ = { + isa = PBXGroup; + children = ( + FCCB4BB481FB461688FE2F29 /* B3DImporter.cpp */, + 42E68041B1C442E3B49FC304 /* B3DImporter.h */, + ); + name = B3D; + sourceTree = ""; + }; + A7F45F8E82C445EBA7D67C36 /* Assbin */ = { + isa = PBXGroup; + children = ( + 6389F68312384CFD847B1D13 /* AssbinExporter.cpp */, + 6CC21F1D0E4140FE923E4EE6 /* AssbinExporter.h */, + D9FEEF58B24548F782A5D53C /* AssbinLoader.cpp */, + 0CCD090F58EB40ACBBDBBDEE /* AssbinLoader.h */, + ); + name = Assbin; + sourceTree = ""; + }; + AF05BC16567A496BB5DCB2F0 /* Products */ = { + isa = PBXGroup; + children = ( + 137A552C590C4E4BBBB1EE31 /* libassimp.3.1.1.a */, + ); + name = Products; + sourceTree = ""; + }; + BCC52F1D5AF74E54A2D69524 = { + isa = PBXGroup; + children = ( + 2DC7AE369B84444B9649035D /* assimp */, + 7F29EF981AB26C4900E9D380 /* libz.1.dylib */, + AF05BC16567A496BB5DCB2F0 /* Products */, + ); + sourceTree = ""; + }; + C3D412701D614559B698CED1 /* Q3BSP */ = { + isa = PBXGroup; + children = ( + 6E82409E9D274D278971F3B0 /* Q3BSPFileData.h */, + A88D56FBEA084A3EA9A0ECB3 /* Q3BSPFileImporter.cpp */, + F898EEA0D9E64425A790587D /* Q3BSPFileImporter.h */, + 4A60A00727F04E049CF3AE33 /* Q3BSPFileParser.cpp */, + 5C15EEB253204E8A8E0D0E38 /* Q3BSPFileParser.h */, + 43C75175738C4119871E8BB0 /* Q3BSPZipArchive.cpp */, + 6454A961FAF44B3E9086D2F8 /* Q3BSPZipArchive.h */, + ); + name = Q3BSP; + sourceTree = ""; + }; + CB3420FADCED418CACDBB584 /* ASE */ = { + isa = PBXGroup; + children = ( + 7C477FA4D89548F1BCEDC5A0 /* ASELoader.cpp */, + 9A61AF384D4D45778698DD7D /* ASELoader.h */, + 929F59CCA32549EC884A5033 /* ASEParser.cpp */, + 27605E75944D41B0B98260A3 /* ASEParser.h */, + ); + name = ASE; + sourceTree = ""; + }; + CB981D90CEF4472191978170 /* MDC */ = { + isa = PBXGroup; + children = ( + 95641498F25A4F6FABBC03A4 /* MDCFileData.h */, + 35E4944C052A4C91BF31DE5F /* MDCLoader.cpp */, + 621E96E95F60421EB6B4525C /* MDCLoader.h */, + DD4E4641B0FE4369BF3775C3 /* MDCNormalTable.h */, + ); + name = MDC; + sourceTree = ""; + }; + CF7D1A0DBB134AC4BCFE3C3F /* NFF */ = { + isa = PBXGroup; + children = ( + 0D6E8E292F594A2DAFF53564 /* NFFLoader.cpp */, + D2869C6AD4814588A45E8F81 /* NFFLoader.h */, + ); + name = NFF; + sourceTree = ""; + }; + D3013C8FC8034BC6859BC020 /* PostProcessing */ = { + isa = PBXGroup; + children = ( + 90DD6CA40A5E41458E11FF3E /* CalcTangentsProcess.cpp */, + BBEE1CF81183473C8492FC03 /* CalcTangentsProcess.h */, + 2ABBB4561E72413EB40702C3 /* ComputeUVMappingProcess.cpp */, + B40FE1BF9D8E411493BBDE0C /* ComputeUVMappingProcess.h */, + 92D8734FFF9742B39A371B70 /* ConvertToLHProcess.cpp */, + 35A9B50143214C63A956FA27 /* ConvertToLHProcess.h */, + 6E20FCC571F144DDBD831CCB /* DeboneProcess.cpp */, + 4770D6DCA1854B4F9B85546A /* DeboneProcess.h */, + BABB7734139C452A9DDEE797 /* FindDegenerates.cpp */, + 4B571231CE2B464BBF1E853F /* FindDegenerates.h */, + C9A101D1311C4E77AAEDD94C /* FindInstancesProcess.cpp */, + 28A938B21261484998F68F4A /* FindInstancesProcess.h */, + 9B4221AA0AD2418FAA45EB64 /* FindInvalidDataProcess.cpp */, + 91FF8B1DCC0644008AE34A04 /* FindInvalidDataProcess.h */, + C54518F708BA4A328D5D7325 /* FixNormalsStep.cpp */, + 8343910BBD464297932B3CE0 /* FixNormalsStep.h */, + 982AE676D2364350B1FBD095 /* GenFaceNormalsProcess.cpp */, + 0FBF026F27F340AD9FABAF02 /* GenFaceNormalsProcess.h */, + A0AED12A1A6D4635A8CFB65A /* GenVertexNormalsProcess.cpp */, + 2AC344FBB0C34D49800F4B8A /* GenVertexNormalsProcess.h */, + 70D5FDFA995E45E6A3E8FD37 /* ImproveCacheLocality.cpp */, + 5FBE72DCC6AC485ABCF89B8C /* ImproveCacheLocality.h */, + B36DA471B9E142FC9425EC45 /* JoinVerticesProcess.cpp */, + 0A941971CBF04E8D900E9799 /* JoinVerticesProcess.h */, + E065DB38B0284196A9283CA3 /* LimitBoneWeightsProcess.cpp */, + DDDE82BDF4F94E0EA35649A4 /* LimitBoneWeightsProcess.h */, + 21B797DAB0E0427C9339AE0F /* MakeVerboseFormat.cpp */, + 0AA53AD6095A4D1088431EED /* MakeVerboseFormat.h */, + AAB9AE5328F843F5A8A3E85C /* OptimizeGraph.cpp */, + 926E8B7924144B349A88023D /* OptimizeGraph.h */, + 2ACC87E846AE4E4A86E1AEF4 /* OptimizeMeshes.cpp */, + DD3D18BC2E58447D9879CB00 /* OptimizeMeshes.h */, + FB55283BC24C4A1CA86C4900 /* PolyTools.h */, + 023C115651B54570AA2040DB /* PretransformVertices.cpp */, + 101172E4EF2E43D988B6B571 /* PretransformVertices.h */, + 890E32C714444692AA016AE5 /* ProcessHelper.cpp */, + A436C47FBF904FECB4A58462 /* ProcessHelper.h */, + ADACEBC4973F4FC0A6FEC68A /* RemoveRedundantMaterials.cpp */, + AD969BA482564C7FAA372F7C /* RemoveRedundantMaterials.h */, + FB4ABA17AF264257BDA4D921 /* RemoveVCProcess.cpp */, + ABDA70358E34432A8A4637F4 /* RemoveVCProcess.h */, + BD9A81E0E27E44718609615B /* SortByPTypeProcess.cpp */, + 16437E08A946431EB2EFA3E0 /* SortByPTypeProcess.h */, + A43641DC9C1B4B578BC40476 /* SplitLargeMeshes.cpp */, + D2EEB62ECBF749AA89146C66 /* SplitLargeMeshes.h */, + DF76D04D95E649BCBC15E64F /* TextureTransform.cpp */, + C5C3ED2BE50D4684994BD533 /* TextureTransform.h */, + 1A0AC303D18A48A69AB3BC03 /* TriangulateProcess.cpp */, + FB2510D46F504365A03EE8A8 /* TriangulateProcess.h */, + 0EF4F7A237F648C2809A8F31 /* ValidateDataStructure.cpp */, + 725DAD1CE04C4F64BDAB7037 /* ValidateDataStructure.h */, + ); + name = PostProcessing; + sourceTree = ""; + }; + DAFF6641A88441AFBE8B99B1 /* COB */ = { + isa = PBXGroup; + children = ( + C84DA0E6CE13493D833BA1C1 /* COBLoader.cpp */, + 445F70426FCC42F088405E86 /* COBLoader.h */, + 9E0572B45F1F4605BD5C919D /* COBScene.h */, + ); + name = COB; + sourceTree = ""; + }; + DB181885BFCC44F594A1FA01 /* Source Files */ = { + isa = PBXGroup; + children = ( + 705D30EE141A48F292783F0E /* Assimp.cpp */, + C16ECC01B4954B07AB547D6C /* AssimpPCH.cpp */, + ); + name = "Source Files"; + sourceTree = ""; + }; + DD5B35196B184EFB820D1FBB /* CSM */ = { + isa = PBXGroup; + children = ( + 77908990BEF04D0881E8AE80 /* CSMLoader.cpp */, + 1BC6B0FE92DD4F38803BC17B /* CSMLoader.h */, + ); + name = CSM; + sourceTree = ""; + }; + EF7D37EB84AF45FC8BF47E7F /* MDL */ = { + isa = PBXGroup; + children = ( + F1A7BD0B5CAE48699FCAEBD1 /* MDLDefaultColorMap.h */, + D5F4108F03D7457EB641836B /* MDLFileData.h */, + AA92FFC8B06D4569AD9C4CB1 /* MDLLoader.cpp */, + E24E950227C848D3A759F5C2 /* MDLLoader.h */, + CEC69808E1844C23B95D3475 /* MDLMaterialLoader.cpp */, + ); + name = MDL; + sourceTree = ""; + }; + F0273EDFDBD34EDAA6678613 /* Q3D */ = { + isa = PBXGroup; + children = ( + C5178B3983F147F3B9BD8217 /* Q3DLoader.cpp */, + 76773A53296549FFA43956A1 /* Q3DLoader.h */, + ); + name = Q3D; + sourceTree = ""; + }; + F61A479614764D11AC3311A8 /* Poly2Tri */ = { + isa = PBXGroup; + children = ( + AE00939F150F413780C8AAD7 /* shapes.cc */, + EE545B58FA1246C792C6AD01 /* shapes.h */, + 50935A81362041BEADF18609 /* utils.h */, + B72D0BA3EF66439F8D582ED3 /* advancing_front.cc */, + DAE82F651F9E4D91A6A6C753 /* advancing_front.h */, + 849EC6315E4A4E5FA06521EA /* cdt.cc */, + 904A696E49D540C2A880792B /* cdt.h */, + 49E993CD86A346869AF473BC /* sweep.cc */, + 62E8551653634972ABBABCAD /* sweep.h */, + 5E10483FBE6D4F4594B460E0 /* sweep_context.cc */, + 267D593135514108B7DEF072 /* sweep_context.h */, + ); + name = Poly2Tri; + sourceTree = ""; + }; + F9261D592F00437EAFC663B5 /* MD2 */ = { + isa = PBXGroup; + children = ( + 21E21BE7CB364AC3AB81E54C /* MD2FileData.h */, + 49B655CCE1314D4E8A94B371 /* MD2Loader.cpp */, + 531FBC4210644C61954EA4C4 /* MD2Loader.h */, + FD84CFD1BD3E4AF4BA622BB8 /* MD2NormalTable.h */, + ); + name = MD2; + sourceTree = ""; + }; + FCFE51BCE7384933A972EDEE /* Header Files */ = { + isa = PBXGroup; + children = ( + 731205CAB88247C095E33412 /* Exporter.hpp */, + B54FBAAF061B40DBA3F48F83 /* IOStream.hpp */, + 86E296E459F94050ACBA3C63 /* IOSystem.hpp */, + B9DFF24FD63A4D9FAE213EED /* Importer.hpp */, + 69AFF47737244CE3BD1653CC /* ProgressHandler.hpp */, + C7B37CA474DF4CE7A5B0658E /* ai_assert.h */, + B441D87EE6ED4EBFB0586B66 /* anim.h */, + B05DC38593F04180B322360B /* camera.h */, + 2F34A6A3C4104625A52BF7C2 /* cexport.h */, + E1313C36045444619026E9FB /* cfileio.h */, + 267A74499024423A86150697 /* cimport.h */, + 0535CB113239433DA7CD7FDE /* color4.h */, + 079B3C75D1014265959C427D /* color4.inl */, + 90949C7A51E84D3595D71A6B /* config.h */, + 9761D873B9604504B9AD7CD5 /* defs.h */, + 4D82A29A8BBF44E69E026F84 /* importerdesc.h */, + 8E2108F568374F65ACE217D1 /* light.h */, + 05EA73C462244F1791039BFB /* material.h */, + 139DFC029C4C44B09952C645 /* material.inl */, + 10E9B0497D844A10BC759A09 /* matrix3x3.h */, + 073189BEE7A5466B9EE817D4 /* matrix3x3.inl */, + BA832069DF214327AE067503 /* matrix4x4.h */, + 4493838DDEE841BF96A0F008 /* matrix4x4.inl */, + E9ED3048A21E483F9C2721F4 /* mesh.h */, + 5F84BDD0D5D345A2BF1E08E1 /* metadata.h */, + 41C2F6D564924BF4ACE75CAC /* postprocess.h */, + 279D2A482FE9402A8F7EC441 /* quaternion.h */, + 97F52051AF4F478FA77AABBC /* quaternion.inl */, + 3B407EAF162843CBA46BC9D4 /* scene.h */, + AE1C2E2C9C424B3684AD9D4A /* texture.h */, + 56DA1CDC223747F4AFBAF953 /* types.h */, + FB1E84BE85A34F98A44BBB2B /* vector2.h */, + B6074B1E864740F787A97EA3 /* vector2.inl */, + 6D72952403D04713A6451654 /* vector3.h */, + 8D53CC35AAED4CE8B9710E04 /* vector3.inl */, + FC0801BA1F95494498A089AF /* version.h */, + ); + name = "Header Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + D9A8BDFCD91D4380A7A667E5 /* assimp */ = { + isa = PBXNativeTarget; + buildConfigurationList = E978D36E8D2F4B8DB9D9FF64 /* Build configuration list for PBXNativeTarget "assimp" */; + buildPhases = ( + 7F01B4BE1AB28080004CED7D /* Run Script to build 'revision.h' */, + C3600D5A4D864B6A9B5EC13F /* Sources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = assimp; + productName = assimp; + productReference = 137A552C590C4E4BBBB1EE31 /* libassimp.3.1.1.a */; + productType = "com.apple.product-type.library.dynamic"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 9DE203BC835F4C81BCDF25CF /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + LastUpgradeCheck = 0630; + }; + buildConfigurationList = 0C36C32B633D49CB92166176 /* Build configuration list for PBXProject "Assimp" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = BCC52F1D5AF74E54A2D69524; + projectDirPath = ../..; + projectRoot = ""; + targets = ( + D9A8BDFCD91D4380A7A667E5 /* assimp */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXShellScriptBuildPhase section */ + 7F01B4BE1AB28080004CED7D /* Run Script to build 'revision.h' */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "$(SRCROOT)/revision.h.in", + ); + name = "Run Script to build 'revision.h'"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/revision.h", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "cat ${SRCROOT}/revision.h.in | sed \"s/@GIT_COMMIT_HASH@/`git rev-parse --short HEAD`/g\" | sed \"s/@GIT_BRANCH@/`git rev-parse --abbrev-ref HEAD`/g\" > ${DERIVED_FILE_DIR}/revision.h"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + C3600D5A4D864B6A9B5EC13F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 498D9244682B4746864377DA /* 3DSConverter.cpp in Sources */, + A2D1DCC827B0499B9CD5A0D6 /* 3DSExporter.cpp in Sources */, + 89C0A1FBD2414597B3F17EBB /* 3DSLoader.cpp in Sources */, + 0C68C4CF4C724B28888ABF43 /* ACLoader.cpp in Sources */, + DECFBA5CCE374CB0B5482B70 /* ASELoader.cpp in Sources */, + 3331B1D6A54A4BFE9A595B4E /* ASEParser.cpp in Sources */, + 13237D91501F46EB8EC4F25C /* AssbinExporter.cpp in Sources */, + F4B87C84ADE24C1D8950F229 /* AssbinLoader.cpp in Sources */, + 3DC78BDA28EA4022BB1F13FD /* Assimp.cpp in Sources */, + 877F5B1F1C3543C18CFB38CD /* AssimpCExport.cpp in Sources */, + 9DE80CA157384A8AA191C9B2 /* AssimpPCH.cpp in Sources */, + D5909BAE18664A6FA736EC80 /* AssxmlExporter.cpp in Sources */, + 231DEB2636A245B6A123B373 /* B3DImporter.cpp in Sources */, + CB2FC9139C4146F2963F7936 /* BVHLoader.cpp in Sources */, + 212780A32DA8413D976187AB /* BaseImporter.cpp in Sources */, + 4429D10DE70A415483DACEAF /* BaseProcess.cpp in Sources */, + 405D15DF00D3447ABC2C78E5 /* Bitmap.cpp in Sources */, + F64BCE7A381744CCA4CE323A /* BlenderBMesh.cpp in Sources */, + D1E81A09A0D24710A4FDE44F /* BlenderDNA.cpp in Sources */, + 8804DB0DABA64EFEB683E3F7 /* BlenderLoader.cpp in Sources */, + 4CC8B99EBE8C4CDF83AE4B25 /* BlenderModifier.cpp in Sources */, + 4DDD54E33C674EE89A85AE97 /* BlenderScene.cpp in Sources */, + FD598E7E17A84C29A4C0F3F4 /* BlenderTessellator.cpp in Sources */, + 98E562C54EC844AA96551B41 /* COBLoader.cpp in Sources */, + A2E37983FB5F43A9A65C6F97 /* CSMLoader.cpp in Sources */, + 4B0EEEEFEB4E434789BB249D /* CalcTangentsProcess.cpp in Sources */, + 4D1710ECAFB640A99F15D406 /* ColladaExporter.cpp in Sources */, + AA55FAFEE2184A3F8464AFC7 /* ColladaLoader.cpp in Sources */, + C715213375A24A18A54D82F8 /* ColladaParser.cpp in Sources */, + 64493DD9B731476BBB5F9BA6 /* ComputeUVMappingProcess.cpp in Sources */, + DAED741B6225426EBEAF5C63 /* ConvertToLHProcess.cpp in Sources */, + 5CBC282D206847F791F2ADAF /* DXFLoader.cpp in Sources */, + 3ED4918301614730B510E884 /* DeboneProcess.cpp in Sources */, + F1B541BC242D4E178B31FEDC /* DefaultIOStream.cpp in Sources */, + 61B4DFF611244C35845961C0 /* DefaultIOSystem.cpp in Sources */, + 9636ACD2FDBC4E809B9FDE46 /* DefaultLogger.cpp in Sources */, + 249B88B0A31A47CA90934CA9 /* Exporter.cpp in Sources */, + A8E506EA650F4D3DB504953D /* FBXAnimation.cpp in Sources */, + 3CC1408ACD3249ECA00408B7 /* FBXBinaryTokenizer.cpp in Sources */, + 1EBC60AC385E4D28B639B182 /* FBXConverter.cpp in Sources */, + 8A3CB60001A3485B859AAA00 /* FBXDeformer.cpp in Sources */, + 1FA6FB6673934D11BFD23F41 /* FBXDocument.cpp in Sources */, + A0285A7F436243969EF1241D /* FBXDocumentUtil.cpp in Sources */, + C4F211D64AC348FDB8D7C67C /* FBXImporter.cpp in Sources */, + C97C468599E940F892D2FCD1 /* FBXMaterial.cpp in Sources */, + 5CD0466AD8454EF88928D43F /* FBXMeshGeometry.cpp in Sources */, + 7C3E0E5CFEEF403B8DC8E0DA /* FBXModel.cpp in Sources */, + A2437AE5CC194212B02F55F6 /* FBXNodeAttribute.cpp in Sources */, + 6F9F7543873B40A3832D1703 /* FBXParser.cpp in Sources */, + EC253D2452644205BD59E69B /* FBXProperties.cpp in Sources */, + F0430145F6F24B03AD9E2394 /* FBXTokenizer.cpp in Sources */, + 6BB503736AA94711A81D26D3 /* FBXUtil.cpp in Sources */, + 227AF9BA6440437DBD69ABAB /* FindDegenerates.cpp in Sources */, + FE0CF0380CE24DFA9DF0964D /* FindInstancesProcess.cpp in Sources */, + FBC467B84AFD4089B1B35B67 /* FindInvalidDataProcess.cpp in Sources */, + 86FA5A1954F54AE1980D50E7 /* FixNormalsStep.cpp in Sources */, + FF8AADE5437849E2AEE95E37 /* GenFaceNormalsProcess.cpp in Sources */, + C3ADFEA536BF4FF3B6C9F587 /* GenVertexNormalsProcess.cpp in Sources */, + 0D2216F34ABC46919011B229 /* HMPLoader.cpp in Sources */, + DCE1B99871964E928F5B4C91 /* IFCBoolean.cpp in Sources */, + A5FC512D048D4BFFAD960679 /* IFCCurve.cpp in Sources */, + 53E7CEA593864ECCBA27EB37 /* IFCGeometry.cpp in Sources */, + 34B01510829644E0B2B8A196 /* IFCLoader.cpp in Sources */, + DAE0A20354BE4889A9D918A0 /* IFCMaterial.cpp in Sources */, + 8C16784DF44B4DB5A9051449 /* IFCOpenings.cpp in Sources */, + B151BDC341654FA681214ACF /* IFCProfile.cpp in Sources */, + 7277E86702084F3D8F7F2595 /* IFCReaderGen.cpp in Sources */, + 1C4683268E00454284E8C1D2 /* IFCUtil.cpp in Sources */, + 56D8494BFA2447EF9DAF0E8B /* IRRLoader.cpp in Sources */, + 880BBABBF77942EEA35AEFC4 /* IRRMeshLoader.cpp in Sources */, + 869150F5FA334A739CA55ED5 /* IRRShared.cpp in Sources */, + B499F78FF5874465B1AA1ECE /* Importer.cpp in Sources */, + 02FE70F552DA42B0AF5BA35E /* ImporterRegistry.cpp in Sources */, + F576B26DE4C944E6AC9A5E4C /* ImproveCacheLocality.cpp in Sources */, + 0C43D2C2124D45AFB210AD77 /* JoinVerticesProcess.cpp in Sources */, + 13F5EF2AA13741BEAA52744A /* LWOAnimation.cpp in Sources */, + FE6A140ABE3444D38A5303AD /* LWOBLoader.cpp in Sources */, + D4CAA1A48B574883B37969A2 /* LWOLoader.cpp in Sources */, + 3091FA821E084C7EAC5C353E /* LWOMaterial.cpp in Sources */, + AF87AB1D5F124C63851EF06D /* LWSLoader.cpp in Sources */, + AC4098FF84BB45D49101F555 /* LimitBoneWeightsProcess.cpp in Sources */, + F555CEC0C5D349FB855E01B1 /* MD2Loader.cpp in Sources */, + 251969D55FFA442180D0AF58 /* MD3Loader.cpp in Sources */, + 4F3A69E237A1457EA41FBFF2 /* MD5Loader.cpp in Sources */, + 24850C77B93042A5BF680D60 /* MD5Parser.cpp in Sources */, + EDA07283EFBC457CB0331971 /* MDCLoader.cpp in Sources */, + 2A320C69D24C45C3A9D9C14E /* MDLLoader.cpp in Sources */, + C8D153E801784E1CAECCC9F1 /* MDLMaterialLoader.cpp in Sources */, + F632A255678844DEBD7DF103 /* MS3DLoader.cpp in Sources */, + 5861B04C98FF4BF2A1D90C43 /* MakeVerboseFormat.cpp in Sources */, + 12DFE025ED3E4527BA61D494 /* MaterialSystem.cpp in Sources */, + 55E02364DDC84751854342DA /* NDOLoader.cpp in Sources */, + 3F8B686D2E214E2F8C93B12D /* NFFLoader.cpp in Sources */, + 1CB938B3E5994902BABC1F2B /* OFFLoader.cpp in Sources */, + 6ABAC74C1F9A406A921A7662 /* ObjExporter.cpp in Sources */, + 84BA05FFC4B84434A4F2865A /* ObjFileImporter.cpp in Sources */, + BE20AEE5126B4AC6AAC005F4 /* ObjFileMtlImporter.cpp in Sources */, + 856922366B6F4D088324016F /* ObjFileParser.cpp in Sources */, + 92642F0078664ACAA4578492 /* OgreBinarySerializer.cpp in Sources */, + ED1C236FBB204757A45E685C /* OgreImporter.cpp in Sources */, + 6C434551EB1F43C9AE9AE538 /* OgreMaterial.cpp in Sources */, + 3A0E96946CD74F4B856517D2 /* OgreStructs.cpp in Sources */, + 4A42D471540842B1933F1D84 /* OgreXmlSerializer.cpp in Sources */, + 02D9D7977CF34425A1E4D0C1 /* OptimizeGraph.cpp in Sources */, + 3A518149B13B4C88BEEA4650 /* OptimizeMeshes.cpp in Sources */, + 7FD9BBB637FC44A995751DD1 /* PlyExporter.cpp in Sources */, + F91C37C0C4424003ABCB1088 /* PlyLoader.cpp in Sources */, + AD249481F4174272BB86D4F2 /* PlyParser.cpp in Sources */, + 12781B32512D411BA3FBD224 /* PostStepRegistry.cpp in Sources */, + 765FA1339C83494B9D32D909 /* PretransformVertices.cpp in Sources */, + 1AD243EFA96047218513620C /* ProcessHelper.cpp in Sources */, + E846D2F46E724308B3762235 /* Q3BSPFileImporter.cpp in Sources */, + A201839885854EA09DF6F9B5 /* Q3BSPFileParser.cpp in Sources */, + A50FB7E42BEA428299BED42A /* Q3BSPZipArchive.cpp in Sources */, + B0F2D168DB044D4A93BB59F5 /* Q3DLoader.cpp in Sources */, + 25EBF16E84324F5C89A7F3FB /* RawLoader.cpp in Sources */, + BAE97CFFFDE34E9BA9E0B480 /* RemoveComments.cpp in Sources */, + 6B1CE2A7564543E79A391FA1 /* RemoveRedundantMaterials.cpp in Sources */, + E3BA3531AA8943DF8AF5215C /* RemoveVCProcess.cpp in Sources */, + 90CB3F9403F04B91A033FA6D /* SGSpatialSort.cpp in Sources */, + 5604BB8263B043F9B3778D0D /* SMDLoader.cpp in Sources */, + A985EFF885964FB09421FDA6 /* STEPFileEncoding.cpp in Sources */, + 74DCE45262FD417BB86348AC /* STEPFileReader.cpp in Sources */, + BABACE2F925443479F870954 /* STLExporter.cpp in Sources */, + B99026162B084974A1299A64 /* STLLoader.cpp in Sources */, + 843E0AFA420542EF8E80C4F6 /* SceneCombiner.cpp in Sources */, + 947A52B0651F4B67BB5A04EF /* ScenePreprocessor.cpp in Sources */, + FEBD430870494EE2BFDAF420 /* SkeletonMeshBuilder.cpp in Sources */, + DDFBB8B2B78B4149B8D0785D /* SortByPTypeProcess.cpp in Sources */, + E3E3C9BAAAE14737BFBDB7AE /* SpatialSort.cpp in Sources */, + 8093E235B7A24B50809263BC /* SplitByBoneCountProcess.cpp in Sources */, + 11DA6BD79AB44123958A3748 /* SplitLargeMeshes.cpp in Sources */, + E2302FC0DE0F4713AF4AE53F /* StandardShapes.cpp in Sources */, + DFC61ACABFFE405CA2D81D97 /* Subdivision.cpp in Sources */, + 44C9833378BF4F0A8D803022 /* TargetAnimation.cpp in Sources */, + 557F2B5892074E42A7774D8F /* TerragenLoader.cpp in Sources */, + 366C5700997F4FE3AE12CCF4 /* TextureTransform.cpp in Sources */, + E89E29B47CA84BF38B5CC0D5 /* TriangulateProcess.cpp in Sources */, + 155A517D4D8040069E88337F /* UnrealLoader.cpp in Sources */, + F70C84CC28084469B0171A67 /* ValidateDataStructure.cpp in Sources */, + 5934E68DD8744098B694D8C9 /* VertexTriangleAdjacency.cpp in Sources */, + 2A010C4331924629B44D800C /* XFileExporter.cpp in Sources */, + 1F903C0A02D34828AD87609E /* XFileImporter.cpp in Sources */, + 414FE97260614C37AE76CCE0 /* XFileParser.cpp in Sources */, + C0264BCE748E464596BF449C /* XGLLoader.cpp in Sources */, + A4352EB42E754AEBAE139C8B /* ConvertUTF.c in Sources */, + F66B9EDC7AAA4013B6651BF1 /* clipper.cpp in Sources */, + 19F3FA59D54E434586302A8E /* irrXML.cpp in Sources */, + 813894EA73344FDD86C37085 /* shapes.cc in Sources */, + 833DBC32CB4A411CA2E1FBF4 /* advancing_front.cc in Sources */, + 89939A908EA344F685D3EC4D /* cdt.cc in Sources */, + 93C93490D1A645159F49630E /* sweep.cc in Sources */, + 6955346149D346A0AEE7AA13 /* sweep_context.cc in Sources */, + 2CA0229CCE5C4D0BB44176AB /* ioapi.c in Sources */, + 6B5223FAAD874885A6B3ED5C /* unzip.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 137567A2412C45B8A269E344 /* RelWithDebInfo */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS = NDEBUG; + MACH_O_TYPE = staticlib; + SUPPORTED_PLATFORMS = "iphonesimulator iphoneos macosx"; + }; + name = RelWithDebInfo; + }; + 8382AB21FE5948768A6ED06A /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + DYLIB_COMPATIBILITY_VERSION = 3.0.0; + DYLIB_CURRENT_VERSION = 3.1.1; + EXECUTABLE_EXTENSION = a; + EXECUTABLE_PREFIX = lib; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_OPTIMIZATION_LEVEL = 3; + GCC_PREPROCESSOR_DEFINITIONS = ( + assimp_EXPORTS, + ASSIMP_BUILD_BOOST_WORKAROUND, + ASSIMP_BUILD_NO_OWN_ZLIB, + ASSIMP_BUILD_NO_C4D_IMPORTER, + ASSIMP_BUILD_DLL_EXPORT, + "$(inherited)", + ); + PRODUCT_NAME = assimp.3.1.1; + SECTORDER_FLAGS = ""; + USER_HEADER_SEARCH_PATHS = "code code/BoostWorkaround include $(inherited)"; + }; + name = Release; + }; + 9604718722A94CBB9F87A9D8 /* MinSizeRel */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS = NDEBUG; + MACH_O_TYPE = staticlib; + SUPPORTED_PLATFORMS = "iphonesimulator iphoneos macosx"; + }; + name = MinSizeRel; + }; + BCDC8BE7426B43EA8E129CD8 /* MinSizeRel */ = { + isa = XCBuildConfiguration; + buildSettings = { + DYLIB_COMPATIBILITY_VERSION = 3.0.0; + DYLIB_CURRENT_VERSION = 3.1.1; + EXECUTABLE_EXTENSION = a; + EXECUTABLE_PREFIX = lib; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_OPTIMIZATION_LEVEL = s; + GCC_PREPROCESSOR_DEFINITIONS = ( + assimp_EXPORTS, + ASSIMP_BUILD_BOOST_WORKAROUND, + ASSIMP_BUILD_NO_OWN_ZLIB, + ASSIMP_BUILD_NO_C4D_IMPORTER, + ASSIMP_BUILD_DLL_EXPORT, + "$(inherited)", + ); + PRODUCT_NAME = assimp.3.1.1; + SECTORDER_FLAGS = ""; + USER_HEADER_SEARCH_PATHS = "code code/BoostWorkaround include $(inherited)"; + }; + name = MinSizeRel; + }; + C58F2FA1D18E452FBFD3B286 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS = "DEBUG=1"; + MACH_O_TYPE = staticlib; + SUPPORTED_PLATFORMS = "iphonesimulator iphoneos macosx"; + }; + name = Debug; + }; + D96F415CC43A4E33AB03FCDA /* RelWithDebInfo */ = { + isa = XCBuildConfiguration; + buildSettings = { + DYLIB_COMPATIBILITY_VERSION = 3.0.0; + DYLIB_CURRENT_VERSION = 3.1.1; + EXECUTABLE_EXTENSION = a; + EXECUTABLE_PREFIX = lib; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 2; + GCC_PREPROCESSOR_DEFINITIONS = ( + assimp_EXPORTS, + ASSIMP_BUILD_BOOST_WORKAROUND, + ASSIMP_BUILD_NO_OWN_ZLIB, + ASSIMP_BUILD_NO_C4D_IMPORTER, + ASSIMP_BUILD_DLL_EXPORT, + "$(inherited)", + ); + PRODUCT_NAME = assimp.3.1.1; + SECTORDER_FLAGS = ""; + USER_HEADER_SEARCH_PATHS = "code code/BoostWorkaround include $(inherited)"; + }; + name = RelWithDebInfo; + }; + DB0088F8DB7C490CBA3CCB90 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS = NDEBUG; + MACH_O_TYPE = staticlib; + SUPPORTED_PLATFORMS = "iphonesimulator iphoneos macosx"; + }; + name = Release; + }; + DEA8514637B640629DA686B3 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + DYLIB_COMPATIBILITY_VERSION = 3.0.0; + DYLIB_CURRENT_VERSION = 3.1.1; + EXECUTABLE_EXTENSION = a; + EXECUTABLE_PREFIX = lib; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + assimp_EXPORTS, + ASSIMP_BUILD_BOOST_WORKAROUND, + ASSIMP_BUILD_NO_OWN_ZLIB, + ASSIMP_BUILD_NO_C4D_IMPORTER, + ASSIMP_BUILD_DLL_EXPORT, + "$(inherited)", + ); + PRODUCT_NAME = assimp.3.1.1; + SECTORDER_FLAGS = ""; + USER_HEADER_SEARCH_PATHS = "code code/BoostWorkaround include $(inherited)"; + }; + name = Debug; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 0C36C32B633D49CB92166176 /* Build configuration list for PBXProject "Assimp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C58F2FA1D18E452FBFD3B286 /* Debug */, + DB0088F8DB7C490CBA3CCB90 /* Release */, + 9604718722A94CBB9F87A9D8 /* MinSizeRel */, + 137567A2412C45B8A269E344 /* RelWithDebInfo */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; + E978D36E8D2F4B8DB9D9FF64 /* Build configuration list for PBXNativeTarget "assimp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DEA8514637B640629DA686B3 /* Debug */, + 8382AB21FE5948768A6ED06A /* Release */, + BCDC8BE7426B43EA8E129CD8 /* MinSizeRel */, + D96F415CC43A4E33AB03FCDA /* RelWithDebInfo */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; +/* End XCConfigurationList section */ + }; + rootObject = 9DE203BC835F4C81BCDF25CF /* Project object */; +} From ca463fca9a63ac95156b30573b445d26d3e981b4 Mon Sep 17 00:00:00 2001 From: Wil Shipley Date: Fri, 13 Mar 2015 00:37:02 -0700 Subject: [PATCH 02/51] - Rearranged groups, link against C++ lib explicitly. --- workspaces/xcode6/Assimp.xcodeproj/project.pbxproj | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/workspaces/xcode6/Assimp.xcodeproj/project.pbxproj b/workspaces/xcode6/Assimp.xcodeproj/project.pbxproj index 5efc9edfa..e5a0549cd 100644 --- a/workspaces/xcode6/Assimp.xcodeproj/project.pbxproj +++ b/workspaces/xcode6/Assimp.xcodeproj/project.pbxproj @@ -362,7 +362,8 @@ 7CAF8A3096E04CB983B53CC1 /* BlenderIntermediate.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = BlenderIntermediate.h; path = code/BlenderIntermediate.h; sourceTree = SOURCE_ROOT; }; 7DC4B0B5E57F4F4892CC823E /* MemoryIOWrapper.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = MemoryIOWrapper.h; path = code/MemoryIOWrapper.h; sourceTree = SOURCE_ROOT; }; 7E8BA0D338C9433587BC6C35 /* StreamWriter.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = StreamWriter.h; path = code/StreamWriter.h; sourceTree = SOURCE_ROOT; }; - 7F29EF981AB26C4900E9D380 /* libz.1.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.1.dylib; path = ../../../../../../usr/lib/libz.1.dylib; sourceTree = ""; }; + 7F29EF981AB26C4900E9D380 /* libz.1.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.1.dylib; path = /usr/lib/libz.1.dylib; sourceTree = ""; }; + 7F392D921AB2C7BB00D952EB /* libc++.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libc++.dylib"; path = "/Users/wjs/Source/UberDwelling/Dwelling Test Apps/Dwelling2DBakeTest/../../../../../../usr/lib/libc++.dylib"; sourceTree = ""; }; 7FF72CB6E99E40E19AE0E64C /* MaterialSystem.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = MaterialSystem.cpp; path = code/MaterialSystem.cpp; sourceTree = SOURCE_ROOT; }; 815702BED5644DD5B242F347 /* TerragenLoader.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = TerragenLoader.h; path = code/TerragenLoader.h; sourceTree = SOURCE_ROOT; }; 8299401C3E4A43A18E887DC1 /* SGSpatialSort.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = SGSpatialSort.h; path = code/SGSpatialSort.h; sourceTree = SOURCE_ROOT; }; @@ -1026,6 +1027,15 @@ name = FBX; sourceTree = ""; }; + 7F392D931AB2C7C200D952EB /* Frameworks */ = { + isa = PBXGroup; + children = ( + 7F29EF981AB26C4900E9D380 /* libz.1.dylib */, + 7F392D921AB2C7BB00D952EB /* libc++.dylib */, + ); + name = Frameworks; + sourceTree = ""; + }; 8438F0F891674542AF8F2302 /* OFFFormat */ = { isa = PBXGroup; children = ( @@ -1191,7 +1201,7 @@ isa = PBXGroup; children = ( 2DC7AE369B84444B9649035D /* assimp */, - 7F29EF981AB26C4900E9D380 /* libz.1.dylib */, + 7F392D931AB2C7C200D952EB /* Frameworks */, AF05BC16567A496BB5DCB2F0 /* Products */, ); sourceTree = ""; From 5438b75c60aa15fdba066e11b110ee727e7fbfef Mon Sep 17 00:00:00 2001 From: Wil Shipley Date: Fri, 13 Mar 2015 18:47:10 -0700 Subject: [PATCH 03/51] - committing the workspace data inside the project file, too, who knows if this is correct --- .../contents.xcworkspacedata | 7 +++ .../xcshareddata/Assimp.xccheckout | 53 +++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 workspaces/xcode6/Assimp.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 workspaces/xcode6/Assimp.xcodeproj/project.xcworkspace/xcshareddata/Assimp.xccheckout diff --git a/workspaces/xcode6/Assimp.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/workspaces/xcode6/Assimp.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..0abcc1fa5 --- /dev/null +++ b/workspaces/xcode6/Assimp.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/workspaces/xcode6/Assimp.xcodeproj/project.xcworkspace/xcshareddata/Assimp.xccheckout b/workspaces/xcode6/Assimp.xcodeproj/project.xcworkspace/xcshareddata/Assimp.xccheckout new file mode 100644 index 000000000..475229dbd --- /dev/null +++ b/workspaces/xcode6/Assimp.xcodeproj/project.xcworkspace/xcshareddata/Assimp.xccheckout @@ -0,0 +1,53 @@ + + + + + IDESourceControlProjectFavoriteDictionaryKey + + IDESourceControlProjectIdentifier + D62E7BFA-CF67-4098-A3F5-28B460E459FD + IDESourceControlProjectName + Assimp + IDESourceControlProjectOriginsDictionary + + AE3F0F79FA18959EE39DE06BF81D40ADA159F259 + https://github.com/delicious-monster/assimp.git + BAB24031A51D728DF843C2AED36E4506ECB1FFC2 + savory:UberDwelling.git + + IDESourceControlProjectPath + workspaces/xcode6/Assimp.xcodeproj + IDESourceControlProjectRelativeInstallPathDictionary + + AE3F0F79FA18959EE39DE06BF81D40ADA159F259 + ../../../.. + BAB24031A51D728DF843C2AED36E4506ECB1FFC2 + ../../../../.. + + IDESourceControlProjectURL + https://github.com/delicious-monster/assimp.git + IDESourceControlProjectVersion + 111 + IDESourceControlProjectWCCIdentifier + AE3F0F79FA18959EE39DE06BF81D40ADA159F259 + IDESourceControlProjectWCConfigurations + + + IDESourceControlRepositoryExtensionIdentifierKey + public.vcs.git + IDESourceControlWCCIdentifierKey + BAB24031A51D728DF843C2AED36E4506ECB1FFC2 + IDESourceControlWCCName + + + + IDESourceControlRepositoryExtensionIdentifierKey + public.vcs.git + IDESourceControlWCCIdentifierKey + AE3F0F79FA18959EE39DE06BF81D40ADA159F259 + IDESourceControlWCCName + assimp + + + + From 1b06d55975c6178b364cc8834d7fabbf42ed896d Mon Sep 17 00:00:00 2001 From: Wil Shipley Date: Fri, 13 Mar 2015 18:47:31 -0700 Subject: [PATCH 04/51] - Needed quotes around path in case of spaces in it. --- workspaces/xcode6/Assimp.xcodeproj/project.pbxproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workspaces/xcode6/Assimp.xcodeproj/project.pbxproj b/workspaces/xcode6/Assimp.xcodeproj/project.pbxproj index e5a0549cd..041796930 100644 --- a/workspaces/xcode6/Assimp.xcodeproj/project.pbxproj +++ b/workspaces/xcode6/Assimp.xcodeproj/project.pbxproj @@ -1489,7 +1489,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "cat ${SRCROOT}/revision.h.in | sed \"s/@GIT_COMMIT_HASH@/`git rev-parse --short HEAD`/g\" | sed \"s/@GIT_BRANCH@/`git rev-parse --abbrev-ref HEAD`/g\" > ${DERIVED_FILE_DIR}/revision.h"; + shellScript = "cat \"${SRCROOT}/revision.h.in\" | sed \"s/@GIT_COMMIT_HASH@/`git rev-parse --short HEAD`/g\" | sed \"s/@GIT_BRANCH@/`git rev-parse --abbrev-ref HEAD`/g\" > \"${DERIVED_FILE_DIR}/revision.h\""; }; /* End PBXShellScriptBuildPhase section */ From e37b306234f18a21e57d78281665f3a14451133c Mon Sep 17 00:00:00 2001 From: Wil Shipley Date: Sat, 14 Mar 2015 15:59:48 -0700 Subject: [PATCH 05/51] - Build as static library FOR REAL, not dylib. --- .../xcode6/Assimp.xcodeproj/project.pbxproj | 934 ++++++++++-------- .../xcshareddata/xcschemes/assimp.xcscheme | 77 ++ 2 files changed, 605 insertions(+), 406 deletions(-) create mode 100644 workspaces/xcode6/Assimp.xcodeproj/xcshareddata/xcschemes/assimp.xcscheme diff --git a/workspaces/xcode6/Assimp.xcodeproj/project.pbxproj b/workspaces/xcode6/Assimp.xcodeproj/project.pbxproj index 041796930..3286d931b 100644 --- a/workspaces/xcode6/Assimp.xcodeproj/project.pbxproj +++ b/workspaces/xcode6/Assimp.xcodeproj/project.pbxproj @@ -7,161 +7,161 @@ objects = { /* Begin PBXBuildFile section */ - 02D9D7977CF34425A1E4D0C1 /* OptimizeGraph.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AAB9AE5328F843F5A8A3E85C /* OptimizeGraph.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 02FE70F552DA42B0AF5BA35E /* ImporterRegistry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D029CE902F8045B0B3AFFDDB /* ImporterRegistry.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 0C43D2C2124D45AFB210AD77 /* JoinVerticesProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B36DA471B9E142FC9425EC45 /* JoinVerticesProcess.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 0C68C4CF4C724B28888ABF43 /* ACLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F1076BAC69DB4935A93045A8 /* ACLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 0D2216F34ABC46919011B229 /* HMPLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43ABFF591F374920A5E18A24 /* HMPLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 11DA6BD79AB44123958A3748 /* SplitLargeMeshes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A43641DC9C1B4B578BC40476 /* SplitLargeMeshes.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 12781B32512D411BA3FBD224 /* PostStepRegistry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E663847651834244834CB9F5 /* PostStepRegistry.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 12DFE025ED3E4527BA61D494 /* MaterialSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7FF72CB6E99E40E19AE0E64C /* MaterialSystem.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 13237D91501F46EB8EC4F25C /* AssbinExporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6389F68312384CFD847B1D13 /* AssbinExporter.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 13F5EF2AA13741BEAA52744A /* LWOAnimation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 680C392FFE0B4CC5ABC7CA64 /* LWOAnimation.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 155A517D4D8040069E88337F /* UnrealLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3B8FD96D46314ACD8F157AC3 /* UnrealLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 19F3FA59D54E434586302A8E /* irrXML.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 64C6BACDA5DD4139AA26EE81 /* irrXML.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 1AD243EFA96047218513620C /* ProcessHelper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 890E32C714444692AA016AE5 /* ProcessHelper.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 1C4683268E00454284E8C1D2 /* IFCUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 59E3D32E3FC7438DB148537F /* IFCUtil.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 1CB938B3E5994902BABC1F2B /* OFFLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EFD557FE2C3A46D78F070655 /* OFFLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 1EBC60AC385E4D28B639B182 /* FBXConverter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7A56A688A3845768410F500 /* FBXConverter.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 1F903C0A02D34828AD87609E /* XFileImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 06DB494DCE4D47FDA00E8B35 /* XFileImporter.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 1FA6FB6673934D11BFD23F41 /* FBXDocument.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F22D5BA425444A028DA42BEA /* FBXDocument.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 212780A32DA8413D976187AB /* BaseImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A58410FEAA884A2D8D73ACCE /* BaseImporter.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 227AF9BA6440437DBD69ABAB /* FindDegenerates.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BABB7734139C452A9DDEE797 /* FindDegenerates.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 231DEB2636A245B6A123B373 /* B3DImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB4BB481FB461688FE2F29 /* B3DImporter.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 24850C77B93042A5BF680D60 /* MD5Parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0BC5FD00572F4C58B267A0EC /* MD5Parser.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 249B88B0A31A47CA90934CA9 /* Exporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FF4E90FB1A3446F095ECC8BD /* Exporter.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 251969D55FFA442180D0AF58 /* MD3Loader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 563FBACCFD774BDEA4AEAC10 /* MD3Loader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 25EBF16E84324F5C89A7F3FB /* RawLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1D4A669762194B9D9A26DD20 /* RawLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 2A010C4331924629B44D800C /* XFileExporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 435DC362E63D4CCBA68656D3 /* XFileExporter.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 2A320C69D24C45C3A9D9C14E /* MDLLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AA92FFC8B06D4569AD9C4CB1 /* MDLLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 2CA0229CCE5C4D0BB44176AB /* ioapi.c in Sources */ = {isa = PBXBuildFile; fileRef = AF75E6049338489BB256D295 /* ioapi.c */; settings = {COMPILER_FLAGS = ""; }; }; - 3091FA821E084C7EAC5C353E /* LWOMaterial.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ED21FC57A384CE6B4F53C0C /* LWOMaterial.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 3331B1D6A54A4BFE9A595B4E /* ASEParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 929F59CCA32549EC884A5033 /* ASEParser.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 34B01510829644E0B2B8A196 /* IFCLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0E9BB0220704C5D93CE7CE9 /* IFCLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 366C5700997F4FE3AE12CCF4 /* TextureTransform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF76D04D95E649BCBC15E64F /* TextureTransform.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 3A0E96946CD74F4B856517D2 /* OgreStructs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 79A49EFE23E34E1CBA2E4377 /* OgreStructs.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 3A518149B13B4C88BEEA4650 /* OptimizeMeshes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACC87E846AE4E4A86E1AEF4 /* OptimizeMeshes.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 3CC1408ACD3249ECA00408B7 /* FBXBinaryTokenizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1108AC28566B4D2B9F27C691 /* FBXBinaryTokenizer.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 3DC78BDA28EA4022BB1F13FD /* Assimp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 705D30EE141A48F292783F0E /* Assimp.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 3ED4918301614730B510E884 /* DeboneProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6E20FCC571F144DDBD831CCB /* DeboneProcess.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 3F8B686D2E214E2F8C93B12D /* NFFLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0D6E8E292F594A2DAFF53564 /* NFFLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 405D15DF00D3447ABC2C78E5 /* Bitmap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 10238FBD7A9D401A82D667CB /* Bitmap.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 414FE97260614C37AE76CCE0 /* XFileParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 74C02A113B804568A7E39CBC /* XFileParser.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 4429D10DE70A415483DACEAF /* BaseProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAB6BC13FCFE40F5801D0972 /* BaseProcess.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 44C9833378BF4F0A8D803022 /* TargetAnimation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6F65B6129F774AEDB8DC845A /* TargetAnimation.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 498D9244682B4746864377DA /* 3DSConverter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15221A74FC9C4B2AAA7306E3 /* 3DSConverter.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 4A42D471540842B1933F1D84 /* OgreXmlSerializer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EF9F805A4BA4428CA98C9DE5 /* OgreXmlSerializer.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 4B0EEEEFEB4E434789BB249D /* CalcTangentsProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90DD6CA40A5E41458E11FF3E /* CalcTangentsProcess.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 4CC8B99EBE8C4CDF83AE4B25 /* BlenderModifier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3106D75C13874F5AB3EBBFE7 /* BlenderModifier.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 4D1710ECAFB640A99F15D406 /* ColladaExporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1C0527629078403F81CFD117 /* ColladaExporter.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 4DDD54E33C674EE89A85AE97 /* BlenderScene.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE0D259917354C80BE1CC791 /* BlenderScene.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 4F3A69E237A1457EA41FBFF2 /* MD5Loader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A277DBC1EFB944F995659A20 /* MD5Loader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 53E7CEA593864ECCBA27EB37 /* IFCGeometry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3267EBBA6EEB435F83FF25E4 /* IFCGeometry.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 557F2B5892074E42A7774D8F /* TerragenLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4866DA5A7BFD49F79B61CBF8 /* TerragenLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 55E02364DDC84751854342DA /* NDOLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B4F1B5789CA540C78FB9219D /* NDOLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 5604BB8263B043F9B3778D0D /* SMDLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FD9BEC6B8A264AB092F98E20 /* SMDLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 56D8494BFA2447EF9DAF0E8B /* IRRLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97DFA90F9D0C4B999C150B10 /* IRRLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 5861B04C98FF4BF2A1D90C43 /* MakeVerboseFormat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 21B797DAB0E0427C9339AE0F /* MakeVerboseFormat.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 5934E68DD8744098B694D8C9 /* VertexTriangleAdjacency.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0AAF26EBF0A64ABDB840BA64 /* VertexTriangleAdjacency.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 5CBC282D206847F791F2ADAF /* DXFLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 466D6B9A7CCD402D9AA87071 /* DXFLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 5CD0466AD8454EF88928D43F /* FBXMeshGeometry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42E110B9E6924AF9B55AE65A /* FBXMeshGeometry.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 61B4DFF611244C35845961C0 /* DefaultIOSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1D502654EF864101A2DA9476 /* DefaultIOSystem.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 64493DD9B731476BBB5F9BA6 /* ComputeUVMappingProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ABBB4561E72413EB40702C3 /* ComputeUVMappingProcess.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 6955346149D346A0AEE7AA13 /* sweep_context.cc in Sources */ = {isa = PBXBuildFile; fileRef = 5E10483FBE6D4F4594B460E0 /* sweep_context.cc */; settings = {COMPILER_FLAGS = ""; }; }; - 6ABAC74C1F9A406A921A7662 /* ObjExporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE811A81663A492A84E13937 /* ObjExporter.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 6B1CE2A7564543E79A391FA1 /* RemoveRedundantMaterials.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ADACEBC4973F4FC0A6FEC68A /* RemoveRedundantMaterials.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 6B5223FAAD874885A6B3ED5C /* unzip.c in Sources */ = {isa = PBXBuildFile; fileRef = 973D4231A4AA4925B019FEEE /* unzip.c */; settings = {COMPILER_FLAGS = ""; }; }; - 6BB503736AA94711A81D26D3 /* FBXUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E6332CD992D447CA910DA456 /* FBXUtil.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 6C434551EB1F43C9AE9AE538 /* OgreMaterial.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F75457C6D026451B9267B65E /* OgreMaterial.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 6F9F7543873B40A3832D1703 /* FBXParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5F373DF3B03B4B848B78EAD2 /* FBXParser.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 7277E86702084F3D8F7F2595 /* IFCReaderGen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3F5D1E6368384D429BA29D5A /* IFCReaderGen.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 74DCE45262FD417BB86348AC /* STEPFileReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDE3ECA98173418A9F997992 /* STEPFileReader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 765FA1339C83494B9D32D909 /* PretransformVertices.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 023C115651B54570AA2040DB /* PretransformVertices.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 7C3E0E5CFEEF403B8DC8E0DA /* FBXModel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A61BDC559CE4186B03C0396 /* FBXModel.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 7FD9BBB637FC44A995751DD1 /* PlyExporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E51043448F1744FFA78526D5 /* PlyExporter.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 8093E235B7A24B50809263BC /* SplitByBoneCountProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99A4349D505F4CC593F48CF6 /* SplitByBoneCountProcess.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 813894EA73344FDD86C37085 /* shapes.cc in Sources */ = {isa = PBXBuildFile; fileRef = AE00939F150F413780C8AAD7 /* shapes.cc */; settings = {COMPILER_FLAGS = ""; }; }; - 833DBC32CB4A411CA2E1FBF4 /* advancing_front.cc in Sources */ = {isa = PBXBuildFile; fileRef = B72D0BA3EF66439F8D582ED3 /* advancing_front.cc */; settings = {COMPILER_FLAGS = ""; }; }; - 843E0AFA420542EF8E80C4F6 /* SceneCombiner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 73A3D87FF2C04C3BA3684F54 /* SceneCombiner.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 84BA05FFC4B84434A4F2865A /* ObjFileImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 862131D4574B4CABA5EC957B /* ObjFileImporter.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 856922366B6F4D088324016F /* ObjFileParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ACF73EEAB2424213BF7158D5 /* ObjFileParser.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 869150F5FA334A739CA55ED5 /* IRRShared.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CC54A231FF6B4B0CABCFD167 /* IRRShared.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 86FA5A1954F54AE1980D50E7 /* FixNormalsStep.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C54518F708BA4A328D5D7325 /* FixNormalsStep.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 877F5B1F1C3543C18CFB38CD /* AssimpCExport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A1A9535EDF9A4FF2B8DABD7D /* AssimpCExport.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 8804DB0DABA64EFEB683E3F7 /* BlenderLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 906F71D342544BF381E1318E /* BlenderLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 880BBABBF77942EEA35AEFC4 /* IRRMeshLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD7FFD53046F4AEB898C0832 /* IRRMeshLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 89939A908EA344F685D3EC4D /* cdt.cc in Sources */ = {isa = PBXBuildFile; fileRef = 849EC6315E4A4E5FA06521EA /* cdt.cc */; settings = {COMPILER_FLAGS = ""; }; }; - 89C0A1FBD2414597B3F17EBB /* 3DSLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02E9476D129940BF84DE6682 /* 3DSLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 8A3CB60001A3485B859AAA00 /* FBXDeformer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9855496CEA774F4FA7FBB862 /* FBXDeformer.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 8C16784DF44B4DB5A9051449 /* IFCOpenings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 74679D2078FD46ED9AC73355 /* IFCOpenings.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 90CB3F9403F04B91A033FA6D /* SGSpatialSort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52836A0629E24447B924750A /* SGSpatialSort.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 92642F0078664ACAA4578492 /* OgreBinarySerializer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 56ADEC4899C047F2839AD791 /* OgreBinarySerializer.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 93C93490D1A645159F49630E /* sweep.cc in Sources */ = {isa = PBXBuildFile; fileRef = 49E993CD86A346869AF473BC /* sweep.cc */; settings = {COMPILER_FLAGS = ""; }; }; - 947A52B0651F4B67BB5A04EF /* ScenePreprocessor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1775DE08FC8647EB896A0FB3 /* ScenePreprocessor.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 9636ACD2FDBC4E809B9FDE46 /* DefaultLogger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A9E9EB834E09420197C3FB8C /* DefaultLogger.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 98E562C54EC844AA96551B41 /* COBLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C84DA0E6CE13493D833BA1C1 /* COBLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 9DE80CA157384A8AA191C9B2 /* AssimpPCH.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C16ECC01B4954B07AB547D6C /* AssimpPCH.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - A0285A7F436243969EF1241D /* FBXDocumentUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB38E7E7661842448F008372 /* FBXDocumentUtil.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - A201839885854EA09DF6F9B5 /* Q3BSPFileParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A60A00727F04E049CF3AE33 /* Q3BSPFileParser.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - A2437AE5CC194212B02F55F6 /* FBXNodeAttribute.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33B70115CA54405F895BA471 /* FBXNodeAttribute.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - A2D1DCC827B0499B9CD5A0D6 /* 3DSExporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ECCBBF2D75A44335AB93C84A /* 3DSExporter.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - A2E37983FB5F43A9A65C6F97 /* CSMLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 77908990BEF04D0881E8AE80 /* CSMLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - A4352EB42E754AEBAE139C8B /* ConvertUTF.c in Sources */ = {isa = PBXBuildFile; fileRef = 9A0960F123634603B15EEA38 /* ConvertUTF.c */; settings = {COMPILER_FLAGS = ""; }; }; - A50FB7E42BEA428299BED42A /* Q3BSPZipArchive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43C75175738C4119871E8BB0 /* Q3BSPZipArchive.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - A5FC512D048D4BFFAD960679 /* IFCCurve.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2E7FD92FFCF441B0A60FC8B4 /* IFCCurve.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - A8E506EA650F4D3DB504953D /* FBXAnimation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EAD34F1AA6664B6B935C9421 /* FBXAnimation.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - A985EFF885964FB09421FDA6 /* STEPFileEncoding.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E11A39E91576445599DF2AC4 /* STEPFileEncoding.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - AA55FAFEE2184A3F8464AFC7 /* ColladaLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A4706D216414D4F8AA72EC9 /* ColladaLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - AC4098FF84BB45D49101F555 /* LimitBoneWeightsProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E065DB38B0284196A9283CA3 /* LimitBoneWeightsProcess.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - AD249481F4174272BB86D4F2 /* PlyParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D504725E540109530E254 /* PlyParser.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - AF87AB1D5F124C63851EF06D /* LWSLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AFF41974881F466A9561BE4B /* LWSLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - B0F2D168DB044D4A93BB59F5 /* Q3DLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C5178B3983F147F3B9BD8217 /* Q3DLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - B151BDC341654FA681214ACF /* IFCProfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46E9F455A3284DB399986293 /* IFCProfile.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - B499F78FF5874465B1AA1ECE /* Importer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9472EFB6831740DD91471337 /* Importer.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - B99026162B084974A1299A64 /* STLLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4D2F1605B9484B08BB33402D /* STLLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - BABACE2F925443479F870954 /* STLExporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 89D2D359BD854D8AA60CB720 /* STLExporter.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - BAE97CFFFDE34E9BA9E0B480 /* RemoveComments.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6A86069DEEDC42B88634F78D /* RemoveComments.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - BE20AEE5126B4AC6AAC005F4 /* ObjFileMtlImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4108529663904025B21E526B /* ObjFileMtlImporter.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - C0264BCE748E464596BF449C /* XGLLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8E395349546A4FDF843E6963 /* XGLLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - C3ADFEA536BF4FF3B6C9F587 /* GenVertexNormalsProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A0AED12A1A6D4635A8CFB65A /* GenVertexNormalsProcess.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - C4F211D64AC348FDB8D7C67C /* FBXImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B4C688FA08F44716855CDD3C /* FBXImporter.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - C715213375A24A18A54D82F8 /* ColladaParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 420D77ED33554D54AA4D50EF /* ColladaParser.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - C8D153E801784E1CAECCC9F1 /* MDLMaterialLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CEC69808E1844C23B95D3475 /* MDLMaterialLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - C97C468599E940F892D2FCD1 /* FBXMaterial.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EE6163EB035149A6B8139DB8 /* FBXMaterial.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - CB2FC9139C4146F2963F7936 /* BVHLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C80B9A3AF4204AE08AA50BAE /* BVHLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - D1E81A09A0D24710A4FDE44F /* BlenderDNA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B65258E349704523BC43904D /* BlenderDNA.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - D4CAA1A48B574883B37969A2 /* LWOLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5A4E05386C094B809A315A07 /* LWOLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - D5909BAE18664A6FA736EC80 /* AssxmlExporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B3E8A1BEF8E74F04AE06871B /* AssxmlExporter.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - DAE0A20354BE4889A9D918A0 /* IFCMaterial.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0014AE5E87A74AAA9EF0EC4B /* IFCMaterial.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - DAED741B6225426EBEAF5C63 /* ConvertToLHProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92D8734FFF9742B39A371B70 /* ConvertToLHProcess.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - DCE1B99871964E928F5B4C91 /* IFCBoolean.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 285D1FDA48EC4DD8933B603E /* IFCBoolean.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - DDFBB8B2B78B4149B8D0785D /* SortByPTypeProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BD9A81E0E27E44718609615B /* SortByPTypeProcess.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - DECFBA5CCE374CB0B5482B70 /* ASELoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C477FA4D89548F1BCEDC5A0 /* ASELoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - DFC61ACABFFE405CA2D81D97 /* Subdivision.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBDEB63CFEB4F2EAA95358D /* Subdivision.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - E2302FC0DE0F4713AF4AE53F /* StandardShapes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C18C5023460E4D17B8C922D7 /* StandardShapes.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - E3BA3531AA8943DF8AF5215C /* RemoveVCProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FB4ABA17AF264257BDA4D921 /* RemoveVCProcess.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - E3E3C9BAAAE14737BFBDB7AE /* SpatialSort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8EEC6646FC044D1E9658A590 /* SpatialSort.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - E846D2F46E724308B3762235 /* Q3BSPFileImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A88D56FBEA084A3EA9A0ECB3 /* Q3BSPFileImporter.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - E89E29B47CA84BF38B5CC0D5 /* TriangulateProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A0AC303D18A48A69AB3BC03 /* TriangulateProcess.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - EC253D2452644205BD59E69B /* FBXProperties.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9D203F78B24C4D7E8E2084A3 /* FBXProperties.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - ED1C236FBB204757A45E685C /* OgreImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 923283A9791E4B4E86D623FC /* OgreImporter.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - EDA07283EFBC457CB0331971 /* MDCLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35E4944C052A4C91BF31DE5F /* MDCLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - F0430145F6F24B03AD9E2394 /* FBXTokenizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CF07D05DC86F4C98BC42FDCF /* FBXTokenizer.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - F1B541BC242D4E178B31FEDC /* DefaultIOStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9FEF4D69EFC4605A4F752E5 /* DefaultIOStream.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - F4B87C84ADE24C1D8950F229 /* AssbinLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D9FEEF58B24548F782A5D53C /* AssbinLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - F555CEC0C5D349FB855E01B1 /* MD2Loader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49B655CCE1314D4E8A94B371 /* MD2Loader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - F576B26DE4C944E6AC9A5E4C /* ImproveCacheLocality.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 70D5FDFA995E45E6A3E8FD37 /* ImproveCacheLocality.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - F632A255678844DEBD7DF103 /* MS3DLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7A990C6FF244DC397B7BA7C /* MS3DLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - F64BCE7A381744CCA4CE323A /* BlenderBMesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 603AFA882AFF49AEAC2C8FA2 /* BlenderBMesh.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - F66B9EDC7AAA4013B6651BF1 /* clipper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 59F8A11A7AED45CC94CEDF28 /* clipper.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - F70C84CC28084469B0171A67 /* ValidateDataStructure.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0EF4F7A237F648C2809A8F31 /* ValidateDataStructure.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - F91C37C0C4424003ABCB1088 /* PlyLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 409C98EE093C499B8A574CA9 /* PlyLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - FBC467B84AFD4089B1B35B67 /* FindInvalidDataProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9B4221AA0AD2418FAA45EB64 /* FindInvalidDataProcess.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - FD598E7E17A84C29A4C0F3F4 /* BlenderTessellator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 12C5DD7A285042EDB1897FAE /* BlenderTessellator.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - FE0CF0380CE24DFA9DF0964D /* FindInstancesProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C9A101D1311C4E77AAEDD94C /* FindInstancesProcess.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - FE6A140ABE3444D38A5303AD /* LWOBLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D629F6BF53864979B7619067 /* LWOBLoader.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - FEBD430870494EE2BFDAF420 /* SkeletonMeshBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9B2827B3E64147E08A5AD334 /* SkeletonMeshBuilder.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - FF8AADE5437849E2AEE95E37 /* GenFaceNormalsProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 982AE676D2364350B1FBD095 /* GenFaceNormalsProcess.cpp */; settings = {COMPILER_FLAGS = ""; }; }; + 7F79242A1AB43E20005A8E5D /* 3DSConverter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15221A74FC9C4B2AAA7306E3 /* 3DSConverter.cpp */; }; + 7F79242B1AB43E20005A8E5D /* 3DSExporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ECCBBF2D75A44335AB93C84A /* 3DSExporter.cpp */; }; + 7F79242C1AB43E20005A8E5D /* 3DSLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02E9476D129940BF84DE6682 /* 3DSLoader.cpp */; }; + 7F79242D1AB43E20005A8E5D /* ACLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F1076BAC69DB4935A93045A8 /* ACLoader.cpp */; }; + 7F79242E1AB43E20005A8E5D /* ASELoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C477FA4D89548F1BCEDC5A0 /* ASELoader.cpp */; }; + 7F79242F1AB43E20005A8E5D /* ASEParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 929F59CCA32549EC884A5033 /* ASEParser.cpp */; }; + 7F7924301AB43E20005A8E5D /* AssbinExporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6389F68312384CFD847B1D13 /* AssbinExporter.cpp */; }; + 7F7924311AB43E20005A8E5D /* AssbinLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D9FEEF58B24548F782A5D53C /* AssbinLoader.cpp */; }; + 7F7924321AB43E20005A8E5D /* Assimp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 705D30EE141A48F292783F0E /* Assimp.cpp */; }; + 7F7924331AB43E20005A8E5D /* AssimpCExport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A1A9535EDF9A4FF2B8DABD7D /* AssimpCExport.cpp */; }; + 7F7924341AB43E20005A8E5D /* AssimpPCH.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C16ECC01B4954B07AB547D6C /* AssimpPCH.cpp */; }; + 7F7924351AB43E20005A8E5D /* AssxmlExporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B3E8A1BEF8E74F04AE06871B /* AssxmlExporter.cpp */; }; + 7F7924361AB43E20005A8E5D /* B3DImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FCCB4BB481FB461688FE2F29 /* B3DImporter.cpp */; }; + 7F7924371AB43E20005A8E5D /* BVHLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C80B9A3AF4204AE08AA50BAE /* BVHLoader.cpp */; }; + 7F7924381AB43E20005A8E5D /* BaseImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A58410FEAA884A2D8D73ACCE /* BaseImporter.cpp */; }; + 7F7924391AB43E20005A8E5D /* BaseProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAB6BC13FCFE40F5801D0972 /* BaseProcess.cpp */; }; + 7F79243A1AB43E20005A8E5D /* Bitmap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 10238FBD7A9D401A82D667CB /* Bitmap.cpp */; }; + 7F79243B1AB43E20005A8E5D /* BlenderBMesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 603AFA882AFF49AEAC2C8FA2 /* BlenderBMesh.cpp */; }; + 7F79243C1AB43E20005A8E5D /* BlenderDNA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B65258E349704523BC43904D /* BlenderDNA.cpp */; }; + 7F79243D1AB43E20005A8E5D /* BlenderLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 906F71D342544BF381E1318E /* BlenderLoader.cpp */; }; + 7F79243E1AB43E20005A8E5D /* BlenderModifier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3106D75C13874F5AB3EBBFE7 /* BlenderModifier.cpp */; }; + 7F79243F1AB43E20005A8E5D /* BlenderScene.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE0D259917354C80BE1CC791 /* BlenderScene.cpp */; }; + 7F7924401AB43E20005A8E5D /* BlenderTessellator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 12C5DD7A285042EDB1897FAE /* BlenderTessellator.cpp */; }; + 7F7924411AB43E20005A8E5D /* COBLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C84DA0E6CE13493D833BA1C1 /* COBLoader.cpp */; }; + 7F7924421AB43E20005A8E5D /* CSMLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 77908990BEF04D0881E8AE80 /* CSMLoader.cpp */; }; + 7F7924431AB43E20005A8E5D /* CalcTangentsProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90DD6CA40A5E41458E11FF3E /* CalcTangentsProcess.cpp */; }; + 7F7924441AB43E20005A8E5D /* ColladaExporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1C0527629078403F81CFD117 /* ColladaExporter.cpp */; }; + 7F7924451AB43E20005A8E5D /* ColladaLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A4706D216414D4F8AA72EC9 /* ColladaLoader.cpp */; }; + 7F7924461AB43E20005A8E5D /* ColladaParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 420D77ED33554D54AA4D50EF /* ColladaParser.cpp */; }; + 7F7924471AB43E20005A8E5D /* ComputeUVMappingProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ABBB4561E72413EB40702C3 /* ComputeUVMappingProcess.cpp */; }; + 7F7924481AB43E20005A8E5D /* ConvertToLHProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 92D8734FFF9742B39A371B70 /* ConvertToLHProcess.cpp */; }; + 7F7924491AB43E20005A8E5D /* DXFLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 466D6B9A7CCD402D9AA87071 /* DXFLoader.cpp */; }; + 7F79244A1AB43E20005A8E5D /* DeboneProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6E20FCC571F144DDBD831CCB /* DeboneProcess.cpp */; }; + 7F79244B1AB43E20005A8E5D /* DefaultIOStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9FEF4D69EFC4605A4F752E5 /* DefaultIOStream.cpp */; }; + 7F79244C1AB43E20005A8E5D /* DefaultIOSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1D502654EF864101A2DA9476 /* DefaultIOSystem.cpp */; }; + 7F79244D1AB43E20005A8E5D /* DefaultLogger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A9E9EB834E09420197C3FB8C /* DefaultLogger.cpp */; }; + 7F79244E1AB43E20005A8E5D /* Exporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FF4E90FB1A3446F095ECC8BD /* Exporter.cpp */; }; + 7F79244F1AB43E20005A8E5D /* FBXAnimation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EAD34F1AA6664B6B935C9421 /* FBXAnimation.cpp */; }; + 7F7924501AB43E20005A8E5D /* FBXBinaryTokenizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1108AC28566B4D2B9F27C691 /* FBXBinaryTokenizer.cpp */; }; + 7F7924511AB43E20005A8E5D /* FBXConverter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7A56A688A3845768410F500 /* FBXConverter.cpp */; }; + 7F7924521AB43E20005A8E5D /* FBXDeformer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9855496CEA774F4FA7FBB862 /* FBXDeformer.cpp */; }; + 7F7924531AB43E20005A8E5D /* FBXDocument.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F22D5BA425444A028DA42BEA /* FBXDocument.cpp */; }; + 7F7924541AB43E20005A8E5D /* FBXDocumentUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB38E7E7661842448F008372 /* FBXDocumentUtil.cpp */; }; + 7F7924551AB43E20005A8E5D /* FBXImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B4C688FA08F44716855CDD3C /* FBXImporter.cpp */; }; + 7F7924561AB43E20005A8E5D /* FBXMaterial.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EE6163EB035149A6B8139DB8 /* FBXMaterial.cpp */; }; + 7F7924571AB43E20005A8E5D /* FBXMeshGeometry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42E110B9E6924AF9B55AE65A /* FBXMeshGeometry.cpp */; }; + 7F7924581AB43E20005A8E5D /* FBXModel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A61BDC559CE4186B03C0396 /* FBXModel.cpp */; }; + 7F7924591AB43E20005A8E5D /* FBXNodeAttribute.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33B70115CA54405F895BA471 /* FBXNodeAttribute.cpp */; }; + 7F79245A1AB43E20005A8E5D /* FBXParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5F373DF3B03B4B848B78EAD2 /* FBXParser.cpp */; }; + 7F79245B1AB43E20005A8E5D /* FBXProperties.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9D203F78B24C4D7E8E2084A3 /* FBXProperties.cpp */; }; + 7F79245C1AB43E20005A8E5D /* FBXTokenizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CF07D05DC86F4C98BC42FDCF /* FBXTokenizer.cpp */; }; + 7F79245D1AB43E20005A8E5D /* FBXUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E6332CD992D447CA910DA456 /* FBXUtil.cpp */; }; + 7F79245E1AB43E20005A8E5D /* FindDegenerates.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BABB7734139C452A9DDEE797 /* FindDegenerates.cpp */; }; + 7F79245F1AB43E20005A8E5D /* FindInstancesProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C9A101D1311C4E77AAEDD94C /* FindInstancesProcess.cpp */; }; + 7F7924601AB43E20005A8E5D /* FindInvalidDataProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9B4221AA0AD2418FAA45EB64 /* FindInvalidDataProcess.cpp */; }; + 7F7924611AB43E20005A8E5D /* FixNormalsStep.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C54518F708BA4A328D5D7325 /* FixNormalsStep.cpp */; }; + 7F7924621AB43E20005A8E5D /* GenFaceNormalsProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 982AE676D2364350B1FBD095 /* GenFaceNormalsProcess.cpp */; }; + 7F7924631AB43E20005A8E5D /* GenVertexNormalsProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A0AED12A1A6D4635A8CFB65A /* GenVertexNormalsProcess.cpp */; }; + 7F7924641AB43E20005A8E5D /* HMPLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43ABFF591F374920A5E18A24 /* HMPLoader.cpp */; }; + 7F7924651AB43E20005A8E5D /* IFCBoolean.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 285D1FDA48EC4DD8933B603E /* IFCBoolean.cpp */; }; + 7F7924661AB43E20005A8E5D /* IFCCurve.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2E7FD92FFCF441B0A60FC8B4 /* IFCCurve.cpp */; }; + 7F7924671AB43E20005A8E5D /* IFCGeometry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3267EBBA6EEB435F83FF25E4 /* IFCGeometry.cpp */; }; + 7F7924681AB43E20005A8E5D /* IFCLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0E9BB0220704C5D93CE7CE9 /* IFCLoader.cpp */; }; + 7F7924691AB43E20005A8E5D /* IFCMaterial.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0014AE5E87A74AAA9EF0EC4B /* IFCMaterial.cpp */; }; + 7F79246A1AB43E20005A8E5D /* IFCOpenings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 74679D2078FD46ED9AC73355 /* IFCOpenings.cpp */; }; + 7F79246B1AB43E20005A8E5D /* IFCProfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46E9F455A3284DB399986293 /* IFCProfile.cpp */; }; + 7F79246C1AB43E20005A8E5D /* IFCReaderGen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3F5D1E6368384D429BA29D5A /* IFCReaderGen.cpp */; }; + 7F79246D1AB43E20005A8E5D /* IFCUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 59E3D32E3FC7438DB148537F /* IFCUtil.cpp */; }; + 7F79246E1AB43E20005A8E5D /* IRRLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97DFA90F9D0C4B999C150B10 /* IRRLoader.cpp */; }; + 7F79246F1AB43E20005A8E5D /* IRRMeshLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD7FFD53046F4AEB898C0832 /* IRRMeshLoader.cpp */; }; + 7F7924701AB43E20005A8E5D /* IRRShared.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CC54A231FF6B4B0CABCFD167 /* IRRShared.cpp */; }; + 7F7924711AB43E20005A8E5D /* Importer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9472EFB6831740DD91471337 /* Importer.cpp */; }; + 7F7924721AB43E20005A8E5D /* ImporterRegistry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D029CE902F8045B0B3AFFDDB /* ImporterRegistry.cpp */; }; + 7F7924731AB43E20005A8E5D /* ImproveCacheLocality.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 70D5FDFA995E45E6A3E8FD37 /* ImproveCacheLocality.cpp */; }; + 7F7924741AB43E20005A8E5D /* JoinVerticesProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B36DA471B9E142FC9425EC45 /* JoinVerticesProcess.cpp */; }; + 7F7924751AB43E20005A8E5D /* LWOAnimation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 680C392FFE0B4CC5ABC7CA64 /* LWOAnimation.cpp */; }; + 7F7924761AB43E20005A8E5D /* LWOBLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D629F6BF53864979B7619067 /* LWOBLoader.cpp */; }; + 7F7924771AB43E20005A8E5D /* LWOLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5A4E05386C094B809A315A07 /* LWOLoader.cpp */; }; + 7F7924781AB43E20005A8E5D /* LWOMaterial.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ED21FC57A384CE6B4F53C0C /* LWOMaterial.cpp */; }; + 7F7924791AB43E20005A8E5D /* LWSLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AFF41974881F466A9561BE4B /* LWSLoader.cpp */; }; + 7F79247A1AB43E20005A8E5D /* LimitBoneWeightsProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E065DB38B0284196A9283CA3 /* LimitBoneWeightsProcess.cpp */; }; + 7F79247B1AB43E20005A8E5D /* MD2Loader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49B655CCE1314D4E8A94B371 /* MD2Loader.cpp */; }; + 7F79247C1AB43E20005A8E5D /* MD3Loader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 563FBACCFD774BDEA4AEAC10 /* MD3Loader.cpp */; }; + 7F79247D1AB43E20005A8E5D /* MD5Loader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A277DBC1EFB944F995659A20 /* MD5Loader.cpp */; }; + 7F79247E1AB43E20005A8E5D /* MD5Parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0BC5FD00572F4C58B267A0EC /* MD5Parser.cpp */; }; + 7F79247F1AB43E20005A8E5D /* MDCLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35E4944C052A4C91BF31DE5F /* MDCLoader.cpp */; }; + 7F7924801AB43E20005A8E5D /* MDLLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AA92FFC8B06D4569AD9C4CB1 /* MDLLoader.cpp */; }; + 7F7924811AB43E20005A8E5D /* MDLMaterialLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CEC69808E1844C23B95D3475 /* MDLMaterialLoader.cpp */; }; + 7F7924821AB43E20005A8E5D /* MS3DLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7A990C6FF244DC397B7BA7C /* MS3DLoader.cpp */; }; + 7F7924831AB43E20005A8E5D /* MakeVerboseFormat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 21B797DAB0E0427C9339AE0F /* MakeVerboseFormat.cpp */; }; + 7F7924841AB43E20005A8E5D /* MaterialSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7FF72CB6E99E40E19AE0E64C /* MaterialSystem.cpp */; }; + 7F7924851AB43E20005A8E5D /* NDOLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B4F1B5789CA540C78FB9219D /* NDOLoader.cpp */; }; + 7F7924861AB43E20005A8E5D /* NFFLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0D6E8E292F594A2DAFF53564 /* NFFLoader.cpp */; }; + 7F7924871AB43E20005A8E5D /* OFFLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EFD557FE2C3A46D78F070655 /* OFFLoader.cpp */; }; + 7F7924881AB43E20005A8E5D /* ObjExporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE811A81663A492A84E13937 /* ObjExporter.cpp */; }; + 7F7924891AB43E20005A8E5D /* ObjFileImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 862131D4574B4CABA5EC957B /* ObjFileImporter.cpp */; }; + 7F79248A1AB43E20005A8E5D /* ObjFileMtlImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4108529663904025B21E526B /* ObjFileMtlImporter.cpp */; }; + 7F79248B1AB43E20005A8E5D /* ObjFileParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ACF73EEAB2424213BF7158D5 /* ObjFileParser.cpp */; }; + 7F79248C1AB43E20005A8E5D /* OgreBinarySerializer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 56ADEC4899C047F2839AD791 /* OgreBinarySerializer.cpp */; }; + 7F79248D1AB43E20005A8E5D /* OgreImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 923283A9791E4B4E86D623FC /* OgreImporter.cpp */; }; + 7F79248E1AB43E20005A8E5D /* OgreMaterial.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F75457C6D026451B9267B65E /* OgreMaterial.cpp */; }; + 7F79248F1AB43E20005A8E5D /* OgreStructs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 79A49EFE23E34E1CBA2E4377 /* OgreStructs.cpp */; }; + 7F7924901AB43E20005A8E5D /* OgreXmlSerializer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EF9F805A4BA4428CA98C9DE5 /* OgreXmlSerializer.cpp */; }; + 7F7924911AB43E20005A8E5D /* OptimizeGraph.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AAB9AE5328F843F5A8A3E85C /* OptimizeGraph.cpp */; }; + 7F7924921AB43E20005A8E5D /* OptimizeMeshes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACC87E846AE4E4A86E1AEF4 /* OptimizeMeshes.cpp */; }; + 7F7924931AB43E20005A8E5D /* PlyExporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E51043448F1744FFA78526D5 /* PlyExporter.cpp */; }; + 7F7924941AB43E20005A8E5D /* PlyLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 409C98EE093C499B8A574CA9 /* PlyLoader.cpp */; }; + 7F7924951AB43E20005A8E5D /* PlyParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D504725E540109530E254 /* PlyParser.cpp */; }; + 7F7924961AB43E20005A8E5D /* PostStepRegistry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E663847651834244834CB9F5 /* PostStepRegistry.cpp */; }; + 7F7924971AB43E20005A8E5D /* PretransformVertices.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 023C115651B54570AA2040DB /* PretransformVertices.cpp */; }; + 7F7924981AB43E20005A8E5D /* ProcessHelper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 890E32C714444692AA016AE5 /* ProcessHelper.cpp */; }; + 7F7924991AB43E20005A8E5D /* Q3BSPFileImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A88D56FBEA084A3EA9A0ECB3 /* Q3BSPFileImporter.cpp */; }; + 7F79249A1AB43E20005A8E5D /* Q3BSPFileParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A60A00727F04E049CF3AE33 /* Q3BSPFileParser.cpp */; }; + 7F79249B1AB43E20005A8E5D /* Q3BSPZipArchive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43C75175738C4119871E8BB0 /* Q3BSPZipArchive.cpp */; }; + 7F79249C1AB43E20005A8E5D /* Q3DLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C5178B3983F147F3B9BD8217 /* Q3DLoader.cpp */; }; + 7F79249D1AB43E20005A8E5D /* RawLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1D4A669762194B9D9A26DD20 /* RawLoader.cpp */; }; + 7F79249E1AB43E20005A8E5D /* RemoveComments.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6A86069DEEDC42B88634F78D /* RemoveComments.cpp */; }; + 7F79249F1AB43E20005A8E5D /* RemoveRedundantMaterials.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ADACEBC4973F4FC0A6FEC68A /* RemoveRedundantMaterials.cpp */; }; + 7F7924A01AB43E20005A8E5D /* RemoveVCProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FB4ABA17AF264257BDA4D921 /* RemoveVCProcess.cpp */; }; + 7F7924A11AB43E20005A8E5D /* SGSpatialSort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52836A0629E24447B924750A /* SGSpatialSort.cpp */; }; + 7F7924A21AB43E20005A8E5D /* SMDLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FD9BEC6B8A264AB092F98E20 /* SMDLoader.cpp */; }; + 7F7924A31AB43E20005A8E5D /* STEPFileEncoding.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E11A39E91576445599DF2AC4 /* STEPFileEncoding.cpp */; }; + 7F7924A41AB43E20005A8E5D /* STEPFileReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDE3ECA98173418A9F997992 /* STEPFileReader.cpp */; }; + 7F7924A51AB43E20005A8E5D /* STLExporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 89D2D359BD854D8AA60CB720 /* STLExporter.cpp */; }; + 7F7924A61AB43E20005A8E5D /* STLLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4D2F1605B9484B08BB33402D /* STLLoader.cpp */; }; + 7F7924A71AB43E20005A8E5D /* SceneCombiner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 73A3D87FF2C04C3BA3684F54 /* SceneCombiner.cpp */; }; + 7F7924A81AB43E20005A8E5D /* ScenePreprocessor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1775DE08FC8647EB896A0FB3 /* ScenePreprocessor.cpp */; }; + 7F7924A91AB43E20005A8E5D /* SkeletonMeshBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9B2827B3E64147E08A5AD334 /* SkeletonMeshBuilder.cpp */; }; + 7F7924AA1AB43E20005A8E5D /* SortByPTypeProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BD9A81E0E27E44718609615B /* SortByPTypeProcess.cpp */; }; + 7F7924AB1AB43E20005A8E5D /* SpatialSort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8EEC6646FC044D1E9658A590 /* SpatialSort.cpp */; }; + 7F7924AC1AB43E20005A8E5D /* SplitByBoneCountProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99A4349D505F4CC593F48CF6 /* SplitByBoneCountProcess.cpp */; }; + 7F7924AD1AB43E20005A8E5D /* SplitLargeMeshes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A43641DC9C1B4B578BC40476 /* SplitLargeMeshes.cpp */; }; + 7F7924AE1AB43E20005A8E5D /* StandardShapes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C18C5023460E4D17B8C922D7 /* StandardShapes.cpp */; }; + 7F7924AF1AB43E20005A8E5D /* Subdivision.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBDEB63CFEB4F2EAA95358D /* Subdivision.cpp */; }; + 7F7924B01AB43E20005A8E5D /* TargetAnimation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6F65B6129F774AEDB8DC845A /* TargetAnimation.cpp */; }; + 7F7924B11AB43E20005A8E5D /* TerragenLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4866DA5A7BFD49F79B61CBF8 /* TerragenLoader.cpp */; }; + 7F7924B21AB43E20005A8E5D /* TextureTransform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF76D04D95E649BCBC15E64F /* TextureTransform.cpp */; }; + 7F7924B31AB43E20005A8E5D /* TriangulateProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A0AC303D18A48A69AB3BC03 /* TriangulateProcess.cpp */; }; + 7F7924B41AB43E20005A8E5D /* UnrealLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3B8FD96D46314ACD8F157AC3 /* UnrealLoader.cpp */; }; + 7F7924B51AB43E20005A8E5D /* ValidateDataStructure.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0EF4F7A237F648C2809A8F31 /* ValidateDataStructure.cpp */; }; + 7F7924B61AB43E20005A8E5D /* VertexTriangleAdjacency.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0AAF26EBF0A64ABDB840BA64 /* VertexTriangleAdjacency.cpp */; }; + 7F7924B71AB43E20005A8E5D /* XFileExporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 435DC362E63D4CCBA68656D3 /* XFileExporter.cpp */; }; + 7F7924B81AB43E20005A8E5D /* XFileImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 06DB494DCE4D47FDA00E8B35 /* XFileImporter.cpp */; }; + 7F7924B91AB43E20005A8E5D /* XFileParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 74C02A113B804568A7E39CBC /* XFileParser.cpp */; }; + 7F7924BA1AB43E20005A8E5D /* XGLLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8E395349546A4FDF843E6963 /* XGLLoader.cpp */; }; + 7F7924BB1AB43E20005A8E5D /* ConvertUTF.c in Sources */ = {isa = PBXBuildFile; fileRef = 9A0960F123634603B15EEA38 /* ConvertUTF.c */; }; + 7F7924BC1AB43E20005A8E5D /* clipper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 59F8A11A7AED45CC94CEDF28 /* clipper.cpp */; }; + 7F7924BD1AB43E20005A8E5D /* irrXML.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 64C6BACDA5DD4139AA26EE81 /* irrXML.cpp */; }; + 7F7924BE1AB43E20005A8E5D /* shapes.cc in Sources */ = {isa = PBXBuildFile; fileRef = AE00939F150F413780C8AAD7 /* shapes.cc */; }; + 7F7924BF1AB43E20005A8E5D /* advancing_front.cc in Sources */ = {isa = PBXBuildFile; fileRef = B72D0BA3EF66439F8D582ED3 /* advancing_front.cc */; }; + 7F7924C01AB43E20005A8E5D /* cdt.cc in Sources */ = {isa = PBXBuildFile; fileRef = 849EC6315E4A4E5FA06521EA /* cdt.cc */; }; + 7F7924C11AB43E20005A8E5D /* sweep.cc in Sources */ = {isa = PBXBuildFile; fileRef = 49E993CD86A346869AF473BC /* sweep.cc */; }; + 7F7924C21AB43E20005A8E5D /* sweep_context.cc in Sources */ = {isa = PBXBuildFile; fileRef = 5E10483FBE6D4F4594B460E0 /* sweep_context.cc */; }; + 7F7924C31AB43E20005A8E5D /* ioapi.c in Sources */ = {isa = PBXBuildFile; fileRef = AF75E6049338489BB256D295 /* ioapi.c */; }; + 7F7924C41AB43E20005A8E5D /* unzip.c in Sources */ = {isa = PBXBuildFile; fileRef = 973D4231A4AA4925B019FEEE /* unzip.c */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -195,7 +195,6 @@ 1108AC28566B4D2B9F27C691 /* FBXBinaryTokenizer.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = FBXBinaryTokenizer.cpp; path = code/FBXBinaryTokenizer.cpp; sourceTree = SOURCE_ROOT; }; 12C5DD7A285042EDB1897FAE /* BlenderTessellator.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = BlenderTessellator.cpp; path = code/BlenderTessellator.cpp; sourceTree = SOURCE_ROOT; }; 12E167EBA81B4CD3A241D7AF /* irrXML.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = irrXML.h; path = contrib/irrXML/irrXML.h; sourceTree = SOURCE_ROOT; }; - 137A552C590C4E4BBBB1EE31 /* libassimp.3.1.1.a */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; path = libassimp.3.1.1.a; sourceTree = BUILT_PRODUCTS_DIR; }; 139DFC029C4C44B09952C645 /* material.inl */ = {isa = PBXFileReference; explicitFileType = sourcecode; fileEncoding = 4; name = material.inl; path = include/assimp/material.inl; sourceTree = SOURCE_ROOT; }; 13BFADA520C04B15AE256CC2 /* IFCUtil.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = IFCUtil.h; path = code/IFCUtil.h; sourceTree = SOURCE_ROOT; }; 1520A11AA6E54812939B1FBB /* FileLogStream.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = FileLogStream.h; path = code/FileLogStream.h; sourceTree = SOURCE_ROOT; }; @@ -364,6 +363,7 @@ 7E8BA0D338C9433587BC6C35 /* StreamWriter.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = StreamWriter.h; path = code/StreamWriter.h; sourceTree = SOURCE_ROOT; }; 7F29EF981AB26C4900E9D380 /* libz.1.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.1.dylib; path = /usr/lib/libz.1.dylib; sourceTree = ""; }; 7F392D921AB2C7BB00D952EB /* libc++.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libc++.dylib"; path = "/Users/wjs/Source/UberDwelling/Dwelling Test Apps/Dwelling2DBakeTest/../../../../../../usr/lib/libc++.dylib"; sourceTree = ""; }; + 7F7922801AB43AC3005A8E5D /* libassimp.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libassimp.a; sourceTree = BUILT_PRODUCTS_DIR; }; 7FF72CB6E99E40E19AE0E64C /* MaterialSystem.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = MaterialSystem.cpp; path = code/MaterialSystem.cpp; sourceTree = SOURCE_ROOT; }; 815702BED5644DD5B242F347 /* TerragenLoader.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = TerragenLoader.h; path = code/TerragenLoader.h; sourceTree = SOURCE_ROOT; }; 8299401C3E4A43A18E887DC1 /* SGSpatialSort.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = SGSpatialSort.h; path = code/SGSpatialSort.h; sourceTree = SOURCE_ROOT; }; @@ -567,6 +567,16 @@ FF4E90FB1A3446F095ECC8BD /* Exporter.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = Exporter.cpp; path = code/Exporter.cpp; sourceTree = SOURCE_ROOT; }; /* End PBXFileReference section */ +/* Begin PBXFrameworksBuildPhase section */ + 7F79227D1AB43AC3005A8E5D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + /* Begin PBXGroup section */ 0117589D2B25420F831BA4CE /* MS3D */ = { isa = PBXGroup; @@ -1192,7 +1202,7 @@ AF05BC16567A496BB5DCB2F0 /* Products */ = { isa = PBXGroup; children = ( - 137A552C590C4E4BBBB1EE31 /* libassimp.3.1.1.a */, + 7F7922801AB43AC3005A8E5D /* libassimp.a */, ); name = Products; sourceTree = ""; @@ -1433,12 +1443,13 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - D9A8BDFCD91D4380A7A667E5 /* assimp */ = { + 7F79227F1AB43AC3005A8E5D /* assimp */ = { isa = PBXNativeTarget; - buildConfigurationList = E978D36E8D2F4B8DB9D9FF64 /* Build configuration list for PBXNativeTarget "assimp" */; + buildConfigurationList = 7F7922911AB43AC3005A8E5D /* Build configuration list for PBXNativeTarget "assimp" */; buildPhases = ( - 7F01B4BE1AB28080004CED7D /* Run Script to build 'revision.h' */, - C3600D5A4D864B6A9B5EC13F /* Sources */, + 7F79229B1AB43AF4005A8E5D /* Run Script to build "revision.h" */, + 7F79227C1AB43AC3005A8E5D /* Sources */, + 7F79227D1AB43AC3005A8E5D /* Frameworks */, ); buildRules = ( ); @@ -1446,8 +1457,8 @@ ); name = assimp; productName = assimp; - productReference = 137A552C590C4E4BBBB1EE31 /* libassimp.3.1.1.a */; - productType = "com.apple.product-type.library.dynamic"; + productReference = 7F7922801AB43AC3005A8E5D /* libassimp.a */; + productType = "com.apple.product-type.library.static"; }; /* End PBXNativeTarget section */ @@ -1457,6 +1468,11 @@ attributes = { BuildIndependentTargetsInParallel = YES; LastUpgradeCheck = 0630; + TargetAttributes = { + 7F79227F1AB43AC3005A8E5D = { + CreatedOnToolsVersion = 6.3; + }; + }; }; buildConfigurationList = 0C36C32B633D49CB92166176 /* Build configuration list for PBXProject "Assimp" */; compatibilityVersion = "Xcode 3.2"; @@ -1469,190 +1485,189 @@ projectDirPath = ../..; projectRoot = ""; targets = ( - D9A8BDFCD91D4380A7A667E5 /* assimp */, + 7F79227F1AB43AC3005A8E5D /* assimp */, ); }; /* End PBXProject section */ /* Begin PBXShellScriptBuildPhase section */ - 7F01B4BE1AB28080004CED7D /* Run Script to build 'revision.h' */ = { + 7F79229B1AB43AF4005A8E5D /* Run Script to build "revision.h" */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( - "$(SRCROOT)/revision.h.in", ); - name = "Run Script to build 'revision.h'"; + name = "Run Script to build \"revision.h\""; outputPaths = ( - "$(DERIVED_FILE_DIR)/revision.h", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "cat \"${SRCROOT}/revision.h.in\" | sed \"s/@GIT_COMMIT_HASH@/`git rev-parse --short HEAD`/g\" | sed \"s/@GIT_BRANCH@/`git rev-parse --abbrev-ref HEAD`/g\" > \"${DERIVED_FILE_DIR}/revision.h\""; + shellScript = "mkdir -p \"${DERIVED_FILE_DIR}\"\ncat \"${SRCROOT}/revision.h.in\" | sed \"s/@GIT_COMMIT_HASH@/`git rev-parse --short HEAD`/g\" | sed \"s/@GIT_BRANCH@/`git rev-parse --abbrev-ref HEAD`/g\" > \"${DERIVED_FILE_DIR}/revision.h\""; + showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ - C3600D5A4D864B6A9B5EC13F /* Sources */ = { + 7F79227C1AB43AC3005A8E5D /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 498D9244682B4746864377DA /* 3DSConverter.cpp in Sources */, - A2D1DCC827B0499B9CD5A0D6 /* 3DSExporter.cpp in Sources */, - 89C0A1FBD2414597B3F17EBB /* 3DSLoader.cpp in Sources */, - 0C68C4CF4C724B28888ABF43 /* ACLoader.cpp in Sources */, - DECFBA5CCE374CB0B5482B70 /* ASELoader.cpp in Sources */, - 3331B1D6A54A4BFE9A595B4E /* ASEParser.cpp in Sources */, - 13237D91501F46EB8EC4F25C /* AssbinExporter.cpp in Sources */, - F4B87C84ADE24C1D8950F229 /* AssbinLoader.cpp in Sources */, - 3DC78BDA28EA4022BB1F13FD /* Assimp.cpp in Sources */, - 877F5B1F1C3543C18CFB38CD /* AssimpCExport.cpp in Sources */, - 9DE80CA157384A8AA191C9B2 /* AssimpPCH.cpp in Sources */, - D5909BAE18664A6FA736EC80 /* AssxmlExporter.cpp in Sources */, - 231DEB2636A245B6A123B373 /* B3DImporter.cpp in Sources */, - CB2FC9139C4146F2963F7936 /* BVHLoader.cpp in Sources */, - 212780A32DA8413D976187AB /* BaseImporter.cpp in Sources */, - 4429D10DE70A415483DACEAF /* BaseProcess.cpp in Sources */, - 405D15DF00D3447ABC2C78E5 /* Bitmap.cpp in Sources */, - F64BCE7A381744CCA4CE323A /* BlenderBMesh.cpp in Sources */, - D1E81A09A0D24710A4FDE44F /* BlenderDNA.cpp in Sources */, - 8804DB0DABA64EFEB683E3F7 /* BlenderLoader.cpp in Sources */, - 4CC8B99EBE8C4CDF83AE4B25 /* BlenderModifier.cpp in Sources */, - 4DDD54E33C674EE89A85AE97 /* BlenderScene.cpp in Sources */, - FD598E7E17A84C29A4C0F3F4 /* BlenderTessellator.cpp in Sources */, - 98E562C54EC844AA96551B41 /* COBLoader.cpp in Sources */, - A2E37983FB5F43A9A65C6F97 /* CSMLoader.cpp in Sources */, - 4B0EEEEFEB4E434789BB249D /* CalcTangentsProcess.cpp in Sources */, - 4D1710ECAFB640A99F15D406 /* ColladaExporter.cpp in Sources */, - AA55FAFEE2184A3F8464AFC7 /* ColladaLoader.cpp in Sources */, - C715213375A24A18A54D82F8 /* ColladaParser.cpp in Sources */, - 64493DD9B731476BBB5F9BA6 /* ComputeUVMappingProcess.cpp in Sources */, - DAED741B6225426EBEAF5C63 /* ConvertToLHProcess.cpp in Sources */, - 5CBC282D206847F791F2ADAF /* DXFLoader.cpp in Sources */, - 3ED4918301614730B510E884 /* DeboneProcess.cpp in Sources */, - F1B541BC242D4E178B31FEDC /* DefaultIOStream.cpp in Sources */, - 61B4DFF611244C35845961C0 /* DefaultIOSystem.cpp in Sources */, - 9636ACD2FDBC4E809B9FDE46 /* DefaultLogger.cpp in Sources */, - 249B88B0A31A47CA90934CA9 /* Exporter.cpp in Sources */, - A8E506EA650F4D3DB504953D /* FBXAnimation.cpp in Sources */, - 3CC1408ACD3249ECA00408B7 /* FBXBinaryTokenizer.cpp in Sources */, - 1EBC60AC385E4D28B639B182 /* FBXConverter.cpp in Sources */, - 8A3CB60001A3485B859AAA00 /* FBXDeformer.cpp in Sources */, - 1FA6FB6673934D11BFD23F41 /* FBXDocument.cpp in Sources */, - A0285A7F436243969EF1241D /* FBXDocumentUtil.cpp in Sources */, - C4F211D64AC348FDB8D7C67C /* FBXImporter.cpp in Sources */, - C97C468599E940F892D2FCD1 /* FBXMaterial.cpp in Sources */, - 5CD0466AD8454EF88928D43F /* FBXMeshGeometry.cpp in Sources */, - 7C3E0E5CFEEF403B8DC8E0DA /* FBXModel.cpp in Sources */, - A2437AE5CC194212B02F55F6 /* FBXNodeAttribute.cpp in Sources */, - 6F9F7543873B40A3832D1703 /* FBXParser.cpp in Sources */, - EC253D2452644205BD59E69B /* FBXProperties.cpp in Sources */, - F0430145F6F24B03AD9E2394 /* FBXTokenizer.cpp in Sources */, - 6BB503736AA94711A81D26D3 /* FBXUtil.cpp in Sources */, - 227AF9BA6440437DBD69ABAB /* FindDegenerates.cpp in Sources */, - FE0CF0380CE24DFA9DF0964D /* FindInstancesProcess.cpp in Sources */, - FBC467B84AFD4089B1B35B67 /* FindInvalidDataProcess.cpp in Sources */, - 86FA5A1954F54AE1980D50E7 /* FixNormalsStep.cpp in Sources */, - FF8AADE5437849E2AEE95E37 /* GenFaceNormalsProcess.cpp in Sources */, - C3ADFEA536BF4FF3B6C9F587 /* GenVertexNormalsProcess.cpp in Sources */, - 0D2216F34ABC46919011B229 /* HMPLoader.cpp in Sources */, - DCE1B99871964E928F5B4C91 /* IFCBoolean.cpp in Sources */, - A5FC512D048D4BFFAD960679 /* IFCCurve.cpp in Sources */, - 53E7CEA593864ECCBA27EB37 /* IFCGeometry.cpp in Sources */, - 34B01510829644E0B2B8A196 /* IFCLoader.cpp in Sources */, - DAE0A20354BE4889A9D918A0 /* IFCMaterial.cpp in Sources */, - 8C16784DF44B4DB5A9051449 /* IFCOpenings.cpp in Sources */, - B151BDC341654FA681214ACF /* IFCProfile.cpp in Sources */, - 7277E86702084F3D8F7F2595 /* IFCReaderGen.cpp in Sources */, - 1C4683268E00454284E8C1D2 /* IFCUtil.cpp in Sources */, - 56D8494BFA2447EF9DAF0E8B /* IRRLoader.cpp in Sources */, - 880BBABBF77942EEA35AEFC4 /* IRRMeshLoader.cpp in Sources */, - 869150F5FA334A739CA55ED5 /* IRRShared.cpp in Sources */, - B499F78FF5874465B1AA1ECE /* Importer.cpp in Sources */, - 02FE70F552DA42B0AF5BA35E /* ImporterRegistry.cpp in Sources */, - F576B26DE4C944E6AC9A5E4C /* ImproveCacheLocality.cpp in Sources */, - 0C43D2C2124D45AFB210AD77 /* JoinVerticesProcess.cpp in Sources */, - 13F5EF2AA13741BEAA52744A /* LWOAnimation.cpp in Sources */, - FE6A140ABE3444D38A5303AD /* LWOBLoader.cpp in Sources */, - D4CAA1A48B574883B37969A2 /* LWOLoader.cpp in Sources */, - 3091FA821E084C7EAC5C353E /* LWOMaterial.cpp in Sources */, - AF87AB1D5F124C63851EF06D /* LWSLoader.cpp in Sources */, - AC4098FF84BB45D49101F555 /* LimitBoneWeightsProcess.cpp in Sources */, - F555CEC0C5D349FB855E01B1 /* MD2Loader.cpp in Sources */, - 251969D55FFA442180D0AF58 /* MD3Loader.cpp in Sources */, - 4F3A69E237A1457EA41FBFF2 /* MD5Loader.cpp in Sources */, - 24850C77B93042A5BF680D60 /* MD5Parser.cpp in Sources */, - EDA07283EFBC457CB0331971 /* MDCLoader.cpp in Sources */, - 2A320C69D24C45C3A9D9C14E /* MDLLoader.cpp in Sources */, - C8D153E801784E1CAECCC9F1 /* MDLMaterialLoader.cpp in Sources */, - F632A255678844DEBD7DF103 /* MS3DLoader.cpp in Sources */, - 5861B04C98FF4BF2A1D90C43 /* MakeVerboseFormat.cpp in Sources */, - 12DFE025ED3E4527BA61D494 /* MaterialSystem.cpp in Sources */, - 55E02364DDC84751854342DA /* NDOLoader.cpp in Sources */, - 3F8B686D2E214E2F8C93B12D /* NFFLoader.cpp in Sources */, - 1CB938B3E5994902BABC1F2B /* OFFLoader.cpp in Sources */, - 6ABAC74C1F9A406A921A7662 /* ObjExporter.cpp in Sources */, - 84BA05FFC4B84434A4F2865A /* ObjFileImporter.cpp in Sources */, - BE20AEE5126B4AC6AAC005F4 /* ObjFileMtlImporter.cpp in Sources */, - 856922366B6F4D088324016F /* ObjFileParser.cpp in Sources */, - 92642F0078664ACAA4578492 /* OgreBinarySerializer.cpp in Sources */, - ED1C236FBB204757A45E685C /* OgreImporter.cpp in Sources */, - 6C434551EB1F43C9AE9AE538 /* OgreMaterial.cpp in Sources */, - 3A0E96946CD74F4B856517D2 /* OgreStructs.cpp in Sources */, - 4A42D471540842B1933F1D84 /* OgreXmlSerializer.cpp in Sources */, - 02D9D7977CF34425A1E4D0C1 /* OptimizeGraph.cpp in Sources */, - 3A518149B13B4C88BEEA4650 /* OptimizeMeshes.cpp in Sources */, - 7FD9BBB637FC44A995751DD1 /* PlyExporter.cpp in Sources */, - F91C37C0C4424003ABCB1088 /* PlyLoader.cpp in Sources */, - AD249481F4174272BB86D4F2 /* PlyParser.cpp in Sources */, - 12781B32512D411BA3FBD224 /* PostStepRegistry.cpp in Sources */, - 765FA1339C83494B9D32D909 /* PretransformVertices.cpp in Sources */, - 1AD243EFA96047218513620C /* ProcessHelper.cpp in Sources */, - E846D2F46E724308B3762235 /* Q3BSPFileImporter.cpp in Sources */, - A201839885854EA09DF6F9B5 /* Q3BSPFileParser.cpp in Sources */, - A50FB7E42BEA428299BED42A /* Q3BSPZipArchive.cpp in Sources */, - B0F2D168DB044D4A93BB59F5 /* Q3DLoader.cpp in Sources */, - 25EBF16E84324F5C89A7F3FB /* RawLoader.cpp in Sources */, - BAE97CFFFDE34E9BA9E0B480 /* RemoveComments.cpp in Sources */, - 6B1CE2A7564543E79A391FA1 /* RemoveRedundantMaterials.cpp in Sources */, - E3BA3531AA8943DF8AF5215C /* RemoveVCProcess.cpp in Sources */, - 90CB3F9403F04B91A033FA6D /* SGSpatialSort.cpp in Sources */, - 5604BB8263B043F9B3778D0D /* SMDLoader.cpp in Sources */, - A985EFF885964FB09421FDA6 /* STEPFileEncoding.cpp in Sources */, - 74DCE45262FD417BB86348AC /* STEPFileReader.cpp in Sources */, - BABACE2F925443479F870954 /* STLExporter.cpp in Sources */, - B99026162B084974A1299A64 /* STLLoader.cpp in Sources */, - 843E0AFA420542EF8E80C4F6 /* SceneCombiner.cpp in Sources */, - 947A52B0651F4B67BB5A04EF /* ScenePreprocessor.cpp in Sources */, - FEBD430870494EE2BFDAF420 /* SkeletonMeshBuilder.cpp in Sources */, - DDFBB8B2B78B4149B8D0785D /* SortByPTypeProcess.cpp in Sources */, - E3E3C9BAAAE14737BFBDB7AE /* SpatialSort.cpp in Sources */, - 8093E235B7A24B50809263BC /* SplitByBoneCountProcess.cpp in Sources */, - 11DA6BD79AB44123958A3748 /* SplitLargeMeshes.cpp in Sources */, - E2302FC0DE0F4713AF4AE53F /* StandardShapes.cpp in Sources */, - DFC61ACABFFE405CA2D81D97 /* Subdivision.cpp in Sources */, - 44C9833378BF4F0A8D803022 /* TargetAnimation.cpp in Sources */, - 557F2B5892074E42A7774D8F /* TerragenLoader.cpp in Sources */, - 366C5700997F4FE3AE12CCF4 /* TextureTransform.cpp in Sources */, - E89E29B47CA84BF38B5CC0D5 /* TriangulateProcess.cpp in Sources */, - 155A517D4D8040069E88337F /* UnrealLoader.cpp in Sources */, - F70C84CC28084469B0171A67 /* ValidateDataStructure.cpp in Sources */, - 5934E68DD8744098B694D8C9 /* VertexTriangleAdjacency.cpp in Sources */, - 2A010C4331924629B44D800C /* XFileExporter.cpp in Sources */, - 1F903C0A02D34828AD87609E /* XFileImporter.cpp in Sources */, - 414FE97260614C37AE76CCE0 /* XFileParser.cpp in Sources */, - C0264BCE748E464596BF449C /* XGLLoader.cpp in Sources */, - A4352EB42E754AEBAE139C8B /* ConvertUTF.c in Sources */, - F66B9EDC7AAA4013B6651BF1 /* clipper.cpp in Sources */, - 19F3FA59D54E434586302A8E /* irrXML.cpp in Sources */, - 813894EA73344FDD86C37085 /* shapes.cc in Sources */, - 833DBC32CB4A411CA2E1FBF4 /* advancing_front.cc in Sources */, - 89939A908EA344F685D3EC4D /* cdt.cc in Sources */, - 93C93490D1A645159F49630E /* sweep.cc in Sources */, - 6955346149D346A0AEE7AA13 /* sweep_context.cc in Sources */, - 2CA0229CCE5C4D0BB44176AB /* ioapi.c in Sources */, - 6B5223FAAD874885A6B3ED5C /* unzip.c in Sources */, + 7F79242A1AB43E20005A8E5D /* 3DSConverter.cpp in Sources */, + 7F79242B1AB43E20005A8E5D /* 3DSExporter.cpp in Sources */, + 7F79242C1AB43E20005A8E5D /* 3DSLoader.cpp in Sources */, + 7F79242D1AB43E20005A8E5D /* ACLoader.cpp in Sources */, + 7F79242E1AB43E20005A8E5D /* ASELoader.cpp in Sources */, + 7F79242F1AB43E20005A8E5D /* ASEParser.cpp in Sources */, + 7F7924301AB43E20005A8E5D /* AssbinExporter.cpp in Sources */, + 7F7924311AB43E20005A8E5D /* AssbinLoader.cpp in Sources */, + 7F7924321AB43E20005A8E5D /* Assimp.cpp in Sources */, + 7F7924331AB43E20005A8E5D /* AssimpCExport.cpp in Sources */, + 7F7924341AB43E20005A8E5D /* AssimpPCH.cpp in Sources */, + 7F7924351AB43E20005A8E5D /* AssxmlExporter.cpp in Sources */, + 7F7924361AB43E20005A8E5D /* B3DImporter.cpp in Sources */, + 7F7924371AB43E20005A8E5D /* BVHLoader.cpp in Sources */, + 7F7924381AB43E20005A8E5D /* BaseImporter.cpp in Sources */, + 7F7924391AB43E20005A8E5D /* BaseProcess.cpp in Sources */, + 7F79243A1AB43E20005A8E5D /* Bitmap.cpp in Sources */, + 7F79243B1AB43E20005A8E5D /* BlenderBMesh.cpp in Sources */, + 7F79243C1AB43E20005A8E5D /* BlenderDNA.cpp in Sources */, + 7F79243D1AB43E20005A8E5D /* BlenderLoader.cpp in Sources */, + 7F79243E1AB43E20005A8E5D /* BlenderModifier.cpp in Sources */, + 7F79243F1AB43E20005A8E5D /* BlenderScene.cpp in Sources */, + 7F7924401AB43E20005A8E5D /* BlenderTessellator.cpp in Sources */, + 7F7924411AB43E20005A8E5D /* COBLoader.cpp in Sources */, + 7F7924421AB43E20005A8E5D /* CSMLoader.cpp in Sources */, + 7F7924431AB43E20005A8E5D /* CalcTangentsProcess.cpp in Sources */, + 7F7924441AB43E20005A8E5D /* ColladaExporter.cpp in Sources */, + 7F7924451AB43E20005A8E5D /* ColladaLoader.cpp in Sources */, + 7F7924461AB43E20005A8E5D /* ColladaParser.cpp in Sources */, + 7F7924471AB43E20005A8E5D /* ComputeUVMappingProcess.cpp in Sources */, + 7F7924481AB43E20005A8E5D /* ConvertToLHProcess.cpp in Sources */, + 7F7924491AB43E20005A8E5D /* DXFLoader.cpp in Sources */, + 7F79244A1AB43E20005A8E5D /* DeboneProcess.cpp in Sources */, + 7F79244B1AB43E20005A8E5D /* DefaultIOStream.cpp in Sources */, + 7F79244C1AB43E20005A8E5D /* DefaultIOSystem.cpp in Sources */, + 7F79244D1AB43E20005A8E5D /* DefaultLogger.cpp in Sources */, + 7F79244E1AB43E20005A8E5D /* Exporter.cpp in Sources */, + 7F79244F1AB43E20005A8E5D /* FBXAnimation.cpp in Sources */, + 7F7924501AB43E20005A8E5D /* FBXBinaryTokenizer.cpp in Sources */, + 7F7924511AB43E20005A8E5D /* FBXConverter.cpp in Sources */, + 7F7924521AB43E20005A8E5D /* FBXDeformer.cpp in Sources */, + 7F7924531AB43E20005A8E5D /* FBXDocument.cpp in Sources */, + 7F7924541AB43E20005A8E5D /* FBXDocumentUtil.cpp in Sources */, + 7F7924551AB43E20005A8E5D /* FBXImporter.cpp in Sources */, + 7F7924561AB43E20005A8E5D /* FBXMaterial.cpp in Sources */, + 7F7924571AB43E20005A8E5D /* FBXMeshGeometry.cpp in Sources */, + 7F7924581AB43E20005A8E5D /* FBXModel.cpp in Sources */, + 7F7924591AB43E20005A8E5D /* FBXNodeAttribute.cpp in Sources */, + 7F79245A1AB43E20005A8E5D /* FBXParser.cpp in Sources */, + 7F79245B1AB43E20005A8E5D /* FBXProperties.cpp in Sources */, + 7F79245C1AB43E20005A8E5D /* FBXTokenizer.cpp in Sources */, + 7F79245D1AB43E20005A8E5D /* FBXUtil.cpp in Sources */, + 7F79245E1AB43E20005A8E5D /* FindDegenerates.cpp in Sources */, + 7F79245F1AB43E20005A8E5D /* FindInstancesProcess.cpp in Sources */, + 7F7924601AB43E20005A8E5D /* FindInvalidDataProcess.cpp in Sources */, + 7F7924611AB43E20005A8E5D /* FixNormalsStep.cpp in Sources */, + 7F7924621AB43E20005A8E5D /* GenFaceNormalsProcess.cpp in Sources */, + 7F7924631AB43E20005A8E5D /* GenVertexNormalsProcess.cpp in Sources */, + 7F7924641AB43E20005A8E5D /* HMPLoader.cpp in Sources */, + 7F7924651AB43E20005A8E5D /* IFCBoolean.cpp in Sources */, + 7F7924661AB43E20005A8E5D /* IFCCurve.cpp in Sources */, + 7F7924671AB43E20005A8E5D /* IFCGeometry.cpp in Sources */, + 7F7924681AB43E20005A8E5D /* IFCLoader.cpp in Sources */, + 7F7924691AB43E20005A8E5D /* IFCMaterial.cpp in Sources */, + 7F79246A1AB43E20005A8E5D /* IFCOpenings.cpp in Sources */, + 7F79246B1AB43E20005A8E5D /* IFCProfile.cpp in Sources */, + 7F79246C1AB43E20005A8E5D /* IFCReaderGen.cpp in Sources */, + 7F79246D1AB43E20005A8E5D /* IFCUtil.cpp in Sources */, + 7F79246E1AB43E20005A8E5D /* IRRLoader.cpp in Sources */, + 7F79246F1AB43E20005A8E5D /* IRRMeshLoader.cpp in Sources */, + 7F7924701AB43E20005A8E5D /* IRRShared.cpp in Sources */, + 7F7924711AB43E20005A8E5D /* Importer.cpp in Sources */, + 7F7924721AB43E20005A8E5D /* ImporterRegistry.cpp in Sources */, + 7F7924731AB43E20005A8E5D /* ImproveCacheLocality.cpp in Sources */, + 7F7924741AB43E20005A8E5D /* JoinVerticesProcess.cpp in Sources */, + 7F7924751AB43E20005A8E5D /* LWOAnimation.cpp in Sources */, + 7F7924761AB43E20005A8E5D /* LWOBLoader.cpp in Sources */, + 7F7924771AB43E20005A8E5D /* LWOLoader.cpp in Sources */, + 7F7924781AB43E20005A8E5D /* LWOMaterial.cpp in Sources */, + 7F7924791AB43E20005A8E5D /* LWSLoader.cpp in Sources */, + 7F79247A1AB43E20005A8E5D /* LimitBoneWeightsProcess.cpp in Sources */, + 7F79247B1AB43E20005A8E5D /* MD2Loader.cpp in Sources */, + 7F79247C1AB43E20005A8E5D /* MD3Loader.cpp in Sources */, + 7F79247D1AB43E20005A8E5D /* MD5Loader.cpp in Sources */, + 7F79247E1AB43E20005A8E5D /* MD5Parser.cpp in Sources */, + 7F79247F1AB43E20005A8E5D /* MDCLoader.cpp in Sources */, + 7F7924801AB43E20005A8E5D /* MDLLoader.cpp in Sources */, + 7F7924811AB43E20005A8E5D /* MDLMaterialLoader.cpp in Sources */, + 7F7924821AB43E20005A8E5D /* MS3DLoader.cpp in Sources */, + 7F7924831AB43E20005A8E5D /* MakeVerboseFormat.cpp in Sources */, + 7F7924841AB43E20005A8E5D /* MaterialSystem.cpp in Sources */, + 7F7924851AB43E20005A8E5D /* NDOLoader.cpp in Sources */, + 7F7924861AB43E20005A8E5D /* NFFLoader.cpp in Sources */, + 7F7924871AB43E20005A8E5D /* OFFLoader.cpp in Sources */, + 7F7924881AB43E20005A8E5D /* ObjExporter.cpp in Sources */, + 7F7924891AB43E20005A8E5D /* ObjFileImporter.cpp in Sources */, + 7F79248A1AB43E20005A8E5D /* ObjFileMtlImporter.cpp in Sources */, + 7F79248B1AB43E20005A8E5D /* ObjFileParser.cpp in Sources */, + 7F79248C1AB43E20005A8E5D /* OgreBinarySerializer.cpp in Sources */, + 7F79248D1AB43E20005A8E5D /* OgreImporter.cpp in Sources */, + 7F79248E1AB43E20005A8E5D /* OgreMaterial.cpp in Sources */, + 7F79248F1AB43E20005A8E5D /* OgreStructs.cpp in Sources */, + 7F7924901AB43E20005A8E5D /* OgreXmlSerializer.cpp in Sources */, + 7F7924911AB43E20005A8E5D /* OptimizeGraph.cpp in Sources */, + 7F7924921AB43E20005A8E5D /* OptimizeMeshes.cpp in Sources */, + 7F7924931AB43E20005A8E5D /* PlyExporter.cpp in Sources */, + 7F7924941AB43E20005A8E5D /* PlyLoader.cpp in Sources */, + 7F7924951AB43E20005A8E5D /* PlyParser.cpp in Sources */, + 7F7924961AB43E20005A8E5D /* PostStepRegistry.cpp in Sources */, + 7F7924971AB43E20005A8E5D /* PretransformVertices.cpp in Sources */, + 7F7924981AB43E20005A8E5D /* ProcessHelper.cpp in Sources */, + 7F7924991AB43E20005A8E5D /* Q3BSPFileImporter.cpp in Sources */, + 7F79249A1AB43E20005A8E5D /* Q3BSPFileParser.cpp in Sources */, + 7F79249B1AB43E20005A8E5D /* Q3BSPZipArchive.cpp in Sources */, + 7F79249C1AB43E20005A8E5D /* Q3DLoader.cpp in Sources */, + 7F79249D1AB43E20005A8E5D /* RawLoader.cpp in Sources */, + 7F79249E1AB43E20005A8E5D /* RemoveComments.cpp in Sources */, + 7F79249F1AB43E20005A8E5D /* RemoveRedundantMaterials.cpp in Sources */, + 7F7924A01AB43E20005A8E5D /* RemoveVCProcess.cpp in Sources */, + 7F7924A11AB43E20005A8E5D /* SGSpatialSort.cpp in Sources */, + 7F7924A21AB43E20005A8E5D /* SMDLoader.cpp in Sources */, + 7F7924A31AB43E20005A8E5D /* STEPFileEncoding.cpp in Sources */, + 7F7924A41AB43E20005A8E5D /* STEPFileReader.cpp in Sources */, + 7F7924A51AB43E20005A8E5D /* STLExporter.cpp in Sources */, + 7F7924A61AB43E20005A8E5D /* STLLoader.cpp in Sources */, + 7F7924A71AB43E20005A8E5D /* SceneCombiner.cpp in Sources */, + 7F7924A81AB43E20005A8E5D /* ScenePreprocessor.cpp in Sources */, + 7F7924A91AB43E20005A8E5D /* SkeletonMeshBuilder.cpp in Sources */, + 7F7924AA1AB43E20005A8E5D /* SortByPTypeProcess.cpp in Sources */, + 7F7924AB1AB43E20005A8E5D /* SpatialSort.cpp in Sources */, + 7F7924AC1AB43E20005A8E5D /* SplitByBoneCountProcess.cpp in Sources */, + 7F7924AD1AB43E20005A8E5D /* SplitLargeMeshes.cpp in Sources */, + 7F7924AE1AB43E20005A8E5D /* StandardShapes.cpp in Sources */, + 7F7924AF1AB43E20005A8E5D /* Subdivision.cpp in Sources */, + 7F7924B01AB43E20005A8E5D /* TargetAnimation.cpp in Sources */, + 7F7924B11AB43E20005A8E5D /* TerragenLoader.cpp in Sources */, + 7F7924B21AB43E20005A8E5D /* TextureTransform.cpp in Sources */, + 7F7924B31AB43E20005A8E5D /* TriangulateProcess.cpp in Sources */, + 7F7924B41AB43E20005A8E5D /* UnrealLoader.cpp in Sources */, + 7F7924B51AB43E20005A8E5D /* ValidateDataStructure.cpp in Sources */, + 7F7924B61AB43E20005A8E5D /* VertexTriangleAdjacency.cpp in Sources */, + 7F7924B71AB43E20005A8E5D /* XFileExporter.cpp in Sources */, + 7F7924B81AB43E20005A8E5D /* XFileImporter.cpp in Sources */, + 7F7924B91AB43E20005A8E5D /* XFileParser.cpp in Sources */, + 7F7924BA1AB43E20005A8E5D /* XGLLoader.cpp in Sources */, + 7F7924BB1AB43E20005A8E5D /* ConvertUTF.c in Sources */, + 7F7924BC1AB43E20005A8E5D /* clipper.cpp in Sources */, + 7F7924BD1AB43E20005A8E5D /* irrXML.cpp in Sources */, + 7F7924BE1AB43E20005A8E5D /* shapes.cc in Sources */, + 7F7924BF1AB43E20005A8E5D /* advancing_front.cc in Sources */, + 7F7924C01AB43E20005A8E5D /* cdt.cc in Sources */, + 7F7924C11AB43E20005A8E5D /* sweep.cc in Sources */, + 7F7924C21AB43E20005A8E5D /* sweep_context.cc in Sources */, + 7F7924C31AB43E20005A8E5D /* ioapi.c in Sources */, + 7F7924C41AB43E20005A8E5D /* unzip.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1668,15 +1683,32 @@ }; name = RelWithDebInfo; }; - 8382AB21FE5948768A6ED06A /* Release */ = { + 7F7922921AB43AC3005A8E5D /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DYLIB_COMPATIBILITY_VERSION = 3.0.0; DYLIB_CURRENT_VERSION = 3.1.1; - EXECUTABLE_EXTENSION = a; - EXECUTABLE_PREFIX = lib; - GCC_GENERATE_DEBUGGING_SYMBOLS = NO; - GCC_OPTIMIZATION_LEVEL = 3; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( assimp_EXPORTS, ASSIMP_BUILD_BOOST_WORKAROUND, @@ -1685,12 +1717,171 @@ ASSIMP_BUILD_DLL_EXPORT, "$(inherited)", ); - PRODUCT_NAME = assimp.3.1.1; - SECTORDER_FLAGS = ""; + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; USER_HEADER_SEARCH_PATHS = "code code/BoostWorkaround include $(inherited)"; }; + name = Debug; + }; + 7F7922931AB43AC3005A8E5D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DYLIB_COMPATIBILITY_VERSION = 3.0.0; + DYLIB_CURRENT_VERSION = 3.1.1; + ENABLE_NS_ASSERTIONS = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = fast; + GCC_PREPROCESSOR_DEFINITIONS = ( + assimp_EXPORTS, + ASSIMP_BUILD_BOOST_WORKAROUND, + ASSIMP_BUILD_NO_OWN_ZLIB, + ASSIMP_BUILD_NO_C4D_IMPORTER, + ASSIMP_BUILD_DLL_EXPORT, + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = NO; + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + USER_HEADER_SEARCH_PATHS = "code code/BoostWorkaround include $(inherited)"; + VALIDATE_PRODUCT = YES; + }; name = Release; }; + 7F7922941AB43AC3005A8E5D /* MinSizeRel */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DYLIB_COMPATIBILITY_VERSION = 3.0.0; + DYLIB_CURRENT_VERSION = 3.1.1; + ENABLE_NS_ASSERTIONS = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + assimp_EXPORTS, + ASSIMP_BUILD_BOOST_WORKAROUND, + ASSIMP_BUILD_NO_OWN_ZLIB, + ASSIMP_BUILD_NO_C4D_IMPORTER, + ASSIMP_BUILD_DLL_EXPORT, + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = NO; + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + USER_HEADER_SEARCH_PATHS = "code code/BoostWorkaround include $(inherited)"; + VALIDATE_PRODUCT = YES; + }; + name = MinSizeRel; + }; + 7F7922951AB43AC3005A8E5D /* RelWithDebInfo */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DYLIB_COMPATIBILITY_VERSION = 3.0.0; + DYLIB_CURRENT_VERSION = 3.1.1; + ENABLE_NS_ASSERTIONS = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + assimp_EXPORTS, + ASSIMP_BUILD_BOOST_WORKAROUND, + ASSIMP_BUILD_NO_OWN_ZLIB, + ASSIMP_BUILD_NO_C4D_IMPORTER, + ASSIMP_BUILD_DLL_EXPORT, + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = NO; + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + USER_HEADER_SEARCH_PATHS = "code code/BoostWorkaround include $(inherited)"; + VALIDATE_PRODUCT = YES; + }; + name = RelWithDebInfo; + }; 9604718722A94CBB9F87A9D8 /* MinSizeRel */ = { isa = XCBuildConfiguration; buildSettings = { @@ -1700,29 +1891,6 @@ }; name = MinSizeRel; }; - BCDC8BE7426B43EA8E129CD8 /* MinSizeRel */ = { - isa = XCBuildConfiguration; - buildSettings = { - DYLIB_COMPATIBILITY_VERSION = 3.0.0; - DYLIB_CURRENT_VERSION = 3.1.1; - EXECUTABLE_EXTENSION = a; - EXECUTABLE_PREFIX = lib; - GCC_GENERATE_DEBUGGING_SYMBOLS = NO; - GCC_OPTIMIZATION_LEVEL = s; - GCC_PREPROCESSOR_DEFINITIONS = ( - assimp_EXPORTS, - ASSIMP_BUILD_BOOST_WORKAROUND, - ASSIMP_BUILD_NO_OWN_ZLIB, - ASSIMP_BUILD_NO_C4D_IMPORTER, - ASSIMP_BUILD_DLL_EXPORT, - "$(inherited)", - ); - PRODUCT_NAME = assimp.3.1.1; - SECTORDER_FLAGS = ""; - USER_HEADER_SEARCH_PATHS = "code code/BoostWorkaround include $(inherited)"; - }; - name = MinSizeRel; - }; C58F2FA1D18E452FBFD3B286 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -1732,29 +1900,6 @@ }; name = Debug; }; - D96F415CC43A4E33AB03FCDA /* RelWithDebInfo */ = { - isa = XCBuildConfiguration; - buildSettings = { - DYLIB_COMPATIBILITY_VERSION = 3.0.0; - DYLIB_CURRENT_VERSION = 3.1.1; - EXECUTABLE_EXTENSION = a; - EXECUTABLE_PREFIX = lib; - GCC_GENERATE_DEBUGGING_SYMBOLS = YES; - GCC_OPTIMIZATION_LEVEL = 2; - GCC_PREPROCESSOR_DEFINITIONS = ( - assimp_EXPORTS, - ASSIMP_BUILD_BOOST_WORKAROUND, - ASSIMP_BUILD_NO_OWN_ZLIB, - ASSIMP_BUILD_NO_C4D_IMPORTER, - ASSIMP_BUILD_DLL_EXPORT, - "$(inherited)", - ); - PRODUCT_NAME = assimp.3.1.1; - SECTORDER_FLAGS = ""; - USER_HEADER_SEARCH_PATHS = "code code/BoostWorkaround include $(inherited)"; - }; - name = RelWithDebInfo; - }; DB0088F8DB7C490CBA3CCB90 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { @@ -1764,29 +1909,6 @@ }; name = Release; }; - DEA8514637B640629DA686B3 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - DYLIB_COMPATIBILITY_VERSION = 3.0.0; - DYLIB_CURRENT_VERSION = 3.1.1; - EXECUTABLE_EXTENSION = a; - EXECUTABLE_PREFIX = lib; - GCC_GENERATE_DEBUGGING_SYMBOLS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - assimp_EXPORTS, - ASSIMP_BUILD_BOOST_WORKAROUND, - ASSIMP_BUILD_NO_OWN_ZLIB, - ASSIMP_BUILD_NO_C4D_IMPORTER, - ASSIMP_BUILD_DLL_EXPORT, - "$(inherited)", - ); - PRODUCT_NAME = assimp.3.1.1; - SECTORDER_FLAGS = ""; - USER_HEADER_SEARCH_PATHS = "code code/BoostWorkaround include $(inherited)"; - }; - name = Debug; - }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -1801,13 +1923,13 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; - E978D36E8D2F4B8DB9D9FF64 /* Build configuration list for PBXNativeTarget "assimp" */ = { + 7F7922911AB43AC3005A8E5D /* Build configuration list for PBXNativeTarget "assimp" */ = { isa = XCConfigurationList; buildConfigurations = ( - DEA8514637B640629DA686B3 /* Debug */, - 8382AB21FE5948768A6ED06A /* Release */, - BCDC8BE7426B43EA8E129CD8 /* MinSizeRel */, - D96F415CC43A4E33AB03FCDA /* RelWithDebInfo */, + 7F7922921AB43AC3005A8E5D /* Debug */, + 7F7922931AB43AC3005A8E5D /* Release */, + 7F7922941AB43AC3005A8E5D /* MinSizeRel */, + 7F7922951AB43AC3005A8E5D /* RelWithDebInfo */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; diff --git a/workspaces/xcode6/Assimp.xcodeproj/xcshareddata/xcschemes/assimp.xcscheme b/workspaces/xcode6/Assimp.xcodeproj/xcshareddata/xcschemes/assimp.xcscheme new file mode 100644 index 000000000..e74918baf --- /dev/null +++ b/workspaces/xcode6/Assimp.xcodeproj/xcshareddata/xcschemes/assimp.xcscheme @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 59b08198666da731c80458322dc7b84577aab166 Mon Sep 17 00:00:00 2001 From: Andreas Henne Date: Thu, 19 Mar 2015 17:27:06 +0100 Subject: [PATCH 06/51] STL loader can now handle more than one mesh in a single ascii file. --- code/STLLoader.cpp | 308 ++++++++++++++++++++++++--------------------- 1 file changed, 168 insertions(+), 140 deletions(-) diff --git a/code/STLLoader.cpp b/code/STLLoader.cpp index 987de89d0..8f2a4e18e 100644 --- a/code/STLLoader.cpp +++ b/code/STLLoader.cpp @@ -131,6 +131,19 @@ const aiImporterDesc* STLImporter::GetInfo () const return &desc; } +void addFacesToMesh(aiMesh* pMesh) +{ + pMesh->mFaces = new aiFace[pMesh->mNumFaces]; + for (unsigned int i = 0, p = 0; i < pMesh->mNumFaces;++i) { + + aiFace& face = pMesh->mFaces[i]; + face.mIndices = new unsigned int[face.mNumIndices = 3]; + for (unsigned int o = 0; o < 3;++o,++p) { + face.mIndices[o] = p; + } + } +} + // ------------------------------------------------------------------------------------------------ // Imports the given file into the given scene structure. void STLImporter::InternReadFile( const std::string& pFile, @@ -156,17 +169,8 @@ void STLImporter::InternReadFile( const std::string& pFile, // the default vertex color is light gray. clrColorDefault.r = clrColorDefault.g = clrColorDefault.b = clrColorDefault.a = 0.6f; - // allocate one mesh - pScene->mNumMeshes = 1; - pScene->mMeshes = new aiMesh*[1]; - aiMesh* pMesh = pScene->mMeshes[0] = new aiMesh(); - pMesh->mMaterialIndex = 0; - - // allocate a single node - pScene->mRootNode = new aiNode(); - pScene->mRootNode->mNumMeshes = 1; - pScene->mRootNode->mMeshes = new unsigned int[1]; - pScene->mRootNode->mMeshes[0] = 0; + // allocate a single node + pScene->mRootNode = new aiNode(); bool bMatClr = false; @@ -178,16 +182,12 @@ void STLImporter::InternReadFile( const std::string& pFile, throw DeadlyImportError( "Failed to determine STL storage representation for " + pFile + "."); } - // now copy faces - pMesh->mFaces = new aiFace[pMesh->mNumFaces]; - for (unsigned int i = 0, p = 0; i < pMesh->mNumFaces;++i) { - - aiFace& face = pMesh->mFaces[i]; - face.mIndices = new unsigned int[face.mNumIndices = 3]; - for (unsigned int o = 0; o < 3;++o,++p) { - face.mIndices[o] = p; - } - } + // add all created meshes to the single node + pScene->mRootNode = new aiNode(); + pScene->mRootNode->mNumMeshes = pScene->mNumMeshes; + pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes]; + for (uint i = 0; i < pScene->mNumMeshes; i++) + pScene->mRootNode->mMeshes[i] = i; // create a single default material, using a light gray diffuse color for consistency with // other geometric types (e.g., PLY). @@ -213,140 +213,165 @@ void STLImporter::InternReadFile( const std::string& pFile, // Read an ASCII STL file void STLImporter::LoadASCIIFile() { - aiMesh* pMesh = pScene->mMeshes[0]; + std::vector meshes; + const char* sz = mBuffer; + const char* bufferEnd = mBuffer + fileSize; + std::vector positionBuffer; + std::vector normalBuffer; - const char* sz = mBuffer; - SkipSpaces(&sz); - ai_assert(!IsLineEnd(sz)); + // try to guess how many vertices we could have + // assume we'll need 160 bytes for each face + size_t sizeEstimate = std::max(1u, fileSize / 160u ) * 3; + positionBuffer.reserve(sizeEstimate); + normalBuffer.reserve(sizeEstimate); - sz += 5; // skip the "solid" - SkipSpaces(&sz); - const char* szMe = sz; - while (!::IsSpaceOrNewLine(*sz)) { - sz++; - } + while (IsAsciiSTL(sz, bufferEnd - sz)) + { + aiMesh* pMesh = new aiMesh(); + pMesh->mMaterialIndex = 0; + meshes.push_back(pMesh); - size_t temp; - // setup the name of the node - if ((temp = (size_t)(sz-szMe))) { - if (temp >= MAXLEN) { - throw DeadlyImportError( "STL: Node name too long" ); - } + SkipSpaces(&sz); + ai_assert(!IsLineEnd(sz)); - pScene->mRootNode->mName.length = temp; - memcpy(pScene->mRootNode->mName.data,szMe,temp); - pScene->mRootNode->mName.data[temp] = '\0'; - } - else pScene->mRootNode->mName.Set(""); + sz += 5; // skip the "solid" + SkipSpaces(&sz); + const char* szMe = sz; + while (!::IsSpaceOrNewLine(*sz)) { + sz++; + } - // try to guess how many vertices we could have - // assume we'll need 160 bytes for each face - pMesh->mNumVertices = ( pMesh->mNumFaces = std::max(1u,fileSize / 160u )) * 3; - pMesh->mVertices = new aiVector3D[pMesh->mNumVertices]; - pMesh->mNormals = new aiVector3D[pMesh->mNumVertices]; - - unsigned int curFace = 0, curVertex = 3; - for ( ;; ) - { - // go to the next token - if(!SkipSpacesAndLineEnd(&sz)) - { - // seems we're finished although there was no end marker - DefaultLogger::get()->warn("STL: unexpected EOF. \'endsolid\' keyword was expected"); - break; - } - // facet normal -0.13 -0.13 -0.98 - if (!strncmp(sz,"facet",5) && IsSpaceOrNewLine(*(sz+5))) { + size_t temp; + // setup the name of the node + if ((temp = (size_t)(sz-szMe))) { + if (temp >= MAXLEN) { + throw DeadlyImportError( "STL: Node name too long" ); + } - if (3 != curVertex) { - DefaultLogger::get()->warn("STL: A new facet begins but the old is not yet complete"); - } - if (pMesh->mNumFaces == curFace) { - ai_assert(pMesh->mNumFaces != 0); + pScene->mRootNode->mName.length = temp; + memcpy(pScene->mRootNode->mName.data,szMe,temp); + pScene->mRootNode->mName.data[temp] = '\0'; + } + else pScene->mRootNode->mName.Set(""); - // need to resize the arrays, our size estimate was wrong - unsigned int iNeededSize = (unsigned int)(sz-mBuffer) / pMesh->mNumFaces; - if (iNeededSize <= 160)iNeededSize >>= 1; // prevent endless looping - unsigned int add = (unsigned int)((mBuffer+fileSize)-sz) / iNeededSize; - add += add >> 3; // add 12.5% as buffer - iNeededSize = (pMesh->mNumFaces + add)*3; - aiVector3D* pv = new aiVector3D[iNeededSize]; - memcpy(pv,pMesh->mVertices,pMesh->mNumVertices*sizeof(aiVector3D)); - delete[] pMesh->mVertices; - pMesh->mVertices = pv; - pv = new aiVector3D[iNeededSize]; - memcpy(pv,pMesh->mNormals,pMesh->mNumVertices*sizeof(aiVector3D)); - delete[] pMesh->mNormals; - pMesh->mNormals = pv; + uint faceVertexCounter = 0; + for ( ;; ) + { + // go to the next token + if(!SkipSpacesAndLineEnd(&sz)) + { + // seems we're finished although there was no end marker + DefaultLogger::get()->warn("STL: unexpected EOF. \'endsolid\' keyword was expected"); + break; + } + // facet normal -0.13 -0.13 -0.98 + if (!strncmp(sz,"facet",5) && IsSpaceOrNewLine(*(sz+5))) { - pMesh->mNumVertices = iNeededSize; - pMesh->mNumFaces += add; - } - aiVector3D* vn = &pMesh->mNormals[curFace++*3]; + if (faceVertexCounter != 3) { + DefaultLogger::get()->warn("STL: A new facet begins but the old is not yet complete"); + } + faceVertexCounter = 0; + normalBuffer.push_back(aiVector3D()); + aiVector3D* vn = &normalBuffer.back(); - sz += 6; - curVertex = 0; - SkipSpaces(&sz); - if (strncmp(sz,"normal",6)) { - DefaultLogger::get()->warn("STL: a facet normal vector was expected but not found"); - } - else - { - sz += 7; - SkipSpaces(&sz); - sz = fast_atoreal_move(sz, (float&)vn->x ); - SkipSpaces(&sz); - sz = fast_atoreal_move(sz, (float&)vn->y ); - SkipSpaces(&sz); - sz = fast_atoreal_move(sz, (float&)vn->z ); - *(vn+1) = *vn; - *(vn+2) = *vn; - } - } - // vertex 1.50000 1.50000 0.00000 - else if (!strncmp(sz,"vertex",6) && ::IsSpaceOrNewLine(*(sz+6))) - { - if (3 == curVertex) { - DefaultLogger::get()->error("STL: a facet with more than 3 vertices has been found"); - ++sz; - } - else - { - sz += 7; - SkipSpaces(&sz); - aiVector3D* vn = &pMesh->mVertices[(curFace-1)*3 + curVertex++]; - sz = fast_atoreal_move(sz, (float&)vn->x ); - SkipSpaces(&sz); - sz = fast_atoreal_move(sz, (float&)vn->y ); - SkipSpaces(&sz); - sz = fast_atoreal_move(sz, (float&)vn->z ); - } - } - else if (!::strncmp(sz,"endsolid",8)) { - // finished! - break; - } - // else skip the whole identifier - else { - do { - ++sz; - } while (!::IsSpaceOrNewLine(*sz)); - } - } + sz += 6; + SkipSpaces(&sz); + if (strncmp(sz,"normal",6)) { + DefaultLogger::get()->warn("STL: a facet normal vector was expected but not found"); + } + else + { + sz += 7; + SkipSpaces(&sz); + sz = fast_atoreal_move(sz, (float&)vn->x ); + SkipSpaces(&sz); + sz = fast_atoreal_move(sz, (float&)vn->y ); + SkipSpaces(&sz); + sz = fast_atoreal_move(sz, (float&)vn->z ); + normalBuffer.push_back(*vn); + normalBuffer.push_back(*vn); + } + } + // vertex 1.50000 1.50000 0.00000 + else if (!strncmp(sz,"vertex",6) && ::IsSpaceOrNewLine(*(sz+6))) + { + if (faceVertexCounter >= 3) { + DefaultLogger::get()->error("STL: a facet with more than 3 vertices has been found"); + ++sz; + } + else + { + sz += 7; + SkipSpaces(&sz); + positionBuffer.push_back(aiVector3D()); + aiVector3D* vn = &positionBuffer.back(); + sz = fast_atoreal_move(sz, (float&)vn->x ); + SkipSpaces(&sz); + sz = fast_atoreal_move(sz, (float&)vn->y ); + SkipSpaces(&sz); + sz = fast_atoreal_move(sz, (float&)vn->z ); + faceVertexCounter++; + } + } + else if (!::strncmp(sz,"endsolid",8)) { + do { + ++sz; + } while (!::IsLineEnd(*sz)); + SkipSpacesAndLineEnd(&sz); + // finished! + break; + } + // else skip the whole identifier + else { + do { + ++sz; + } while (!::IsSpaceOrNewLine(*sz)); + } + } - if (!curFace) { - pMesh->mNumFaces = 0; - throw DeadlyImportError("STL: ASCII file is empty or invalid; no data loaded"); - } - pMesh->mNumFaces = curFace; - pMesh->mNumVertices = curFace*3; - // we are finished! + if (positionBuffer.empty()) { + pMesh->mNumFaces = 0; + throw DeadlyImportError("STL: ASCII file is empty or invalid; no data loaded"); + } + if (positionBuffer.size() % 3 != 0) { + pMesh->mNumFaces = 0; + throw DeadlyImportError("STL: Invalid number of vertices"); + } + if (normalBuffer.size() != positionBuffer.size()) { + pMesh->mNumFaces = 0; + throw DeadlyImportError("Normal buffer size does not match position buffer size"); + } + pMesh->mNumFaces = positionBuffer.size() / 3; + pMesh->mNumVertices = positionBuffer.size(); + pMesh->mVertices = new aiVector3D[pMesh->mNumVertices]; + memcpy(pMesh->mVertices, &positionBuffer[0].x, pMesh->mNumVertices * sizeof(aiVector3D)); + positionBuffer.clear(); + pMesh->mNormals = new aiVector3D[pMesh->mNumVertices]; + memcpy(pMesh->mNormals, &normalBuffer[0].x, pMesh->mNumVertices * sizeof(aiVector3D)); + normalBuffer.clear(); + + // now copy faces + addFacesToMesh(pMesh); + } + // now add the loaded meshes + pScene->mNumMeshes = (unsigned int)meshes.size(); + pScene->mMeshes = new aiMesh*[pScene->mNumMeshes]; + for (size_t i = 0; i < meshes.size(); i++) + { + pScene->mMeshes[i] = meshes[i]; + } } // ------------------------------------------------------------------------------------------------ // Read a binary STL file bool STLImporter::LoadBinaryFile() { + // allocate one mesh + pScene->mNumMeshes = 1; + pScene->mMeshes = new aiMesh*[1]; + aiMesh* pMesh = pScene->mMeshes[0] = new aiMesh(); + pMesh->mMaterialIndex = 0; + // skip the first 80 bytes if (fileSize < 84) { throw DeadlyImportError("STL: file is too small for the header"); @@ -374,7 +399,6 @@ bool STLImporter::LoadBinaryFile() const unsigned char* sz = (const unsigned char*)mBuffer + 80; // now read the number of facets - aiMesh* pMesh = pScene->mMeshes[0]; pScene->mRootNode->mName.Set(""); pMesh->mNumFaces = *((uint32_t*)sz); @@ -447,6 +471,10 @@ bool STLImporter::LoadBinaryFile() *(clr+2) = *clr; } } + + // now copy faces + addFacesToMesh(pMesh); + if (bIsMaterialise && !pMesh->mColors[0]) { // use the color as diffuse material color From 816ceeda6915e025cb11af959e0652b015a1c930 Mon Sep 17 00:00:00 2001 From: Andreas Henne Date: Fri, 20 Mar 2015 14:18:26 +0100 Subject: [PATCH 07/51] Eliminated error in MSVC. --- code/STLLoader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/STLLoader.cpp b/code/STLLoader.cpp index 8f2a4e18e..6b9df9d91 100644 --- a/code/STLLoader.cpp +++ b/code/STLLoader.cpp @@ -186,7 +186,7 @@ void STLImporter::InternReadFile( const std::string& pFile, pScene->mRootNode = new aiNode(); pScene->mRootNode->mNumMeshes = pScene->mNumMeshes; pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes]; - for (uint i = 0; i < pScene->mNumMeshes; i++) + for (unsigned int i = 0; i < pScene->mNumMeshes; i++) pScene->mRootNode->mMeshes[i] = i; // create a single default material, using a light gray diffuse color for consistency with @@ -254,7 +254,7 @@ void STLImporter::LoadASCIIFile() } else pScene->mRootNode->mName.Set(""); - uint faceVertexCounter = 0; + unsigned int faceVertexCounter = 0; for ( ;; ) { // go to the next token From 5164b1bd2404ee72351f22c5a47f079426ad24fa Mon Sep 17 00:00:00 2001 From: Wil Shipley Date: Thu, 26 Mar 2015 13:47:53 -0700 Subject: [PATCH 08/51] Turned off several warnings so code doesn't explode with them. Someone who speaks C++ should maybe go back through and see if these warning are really relevant! --- .../xcode6/Assimp.xcodeproj/project.pbxproj | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/workspaces/xcode6/Assimp.xcodeproj/project.pbxproj b/workspaces/xcode6/Assimp.xcodeproj/project.pbxproj index 3286d931b..0fe168f9f 100644 --- a/workspaces/xcode6/Assimp.xcodeproj/project.pbxproj +++ b/workspaces/xcode6/Assimp.xcodeproj/project.pbxproj @@ -1698,7 +1698,6 @@ CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; @@ -1718,12 +1717,8 @@ "$(inherited)", ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.3; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; @@ -1749,7 +1744,6 @@ CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; @@ -1768,12 +1762,8 @@ ASSIMP_BUILD_DLL_EXPORT, "$(inherited)", ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.3; MTL_ENABLE_DEBUG_INFO = NO; OTHER_LDFLAGS = "-ObjC"; @@ -1799,7 +1789,6 @@ CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; @@ -1817,12 +1806,8 @@ ASSIMP_BUILD_DLL_EXPORT, "$(inherited)", ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.3; MTL_ENABLE_DEBUG_INFO = NO; OTHER_LDFLAGS = "-ObjC"; @@ -1848,7 +1833,6 @@ CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; @@ -1866,12 +1850,8 @@ ASSIMP_BUILD_DLL_EXPORT, "$(inherited)", ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.3; MTL_ENABLE_DEBUG_INFO = NO; OTHER_LDFLAGS = "-ObjC"; From 39c662269783fd5934404f1dcc5e51552ecaa981 Mon Sep 17 00:00:00 2001 From: Wil Shipley Date: Tue, 5 May 2015 15:42:01 -0700 Subject: [PATCH 09/51] - Added a generic renderToImage() function to SCNRenderer, so we can share with StackOverflow / Goossens. --- workspaces/xcode6/Assimp.xcodeproj/project.pbxproj | 7 ++++++- .../xcshareddata/xcschemes/assimp.xcscheme | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/workspaces/xcode6/Assimp.xcodeproj/project.pbxproj b/workspaces/xcode6/Assimp.xcodeproj/project.pbxproj index 0fe168f9f..7773fe7bb 100644 --- a/workspaces/xcode6/Assimp.xcodeproj/project.pbxproj +++ b/workspaces/xcode6/Assimp.xcodeproj/project.pbxproj @@ -1467,7 +1467,7 @@ isa = PBXProject; attributes = { BuildIndependentTargetsInParallel = YES; - LastUpgradeCheck = 0630; + LastUpgradeCheck = 0640; TargetAttributes = { 7F79227F1AB43AC3005A8E5D = { CreatedOnToolsVersion = 6.3; @@ -1699,6 +1699,7 @@ CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DYLIB_COMPATIBILITY_VERSION = 3.0.0; @@ -1745,6 +1746,7 @@ CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DYLIB_COMPATIBILITY_VERSION = 3.0.0; @@ -1790,6 +1792,7 @@ CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DYLIB_COMPATIBILITY_VERSION = 3.0.0; @@ -1834,6 +1837,7 @@ CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DYLIB_COMPATIBILITY_VERSION = 3.0.0; @@ -1876,6 +1880,7 @@ buildSettings = { GCC_PREPROCESSOR_DEFINITIONS = "DEBUG=1"; MACH_O_TYPE = staticlib; + ONLY_ACTIVE_ARCH = YES; SUPPORTED_PLATFORMS = "iphonesimulator iphoneos macosx"; }; name = Debug; diff --git a/workspaces/xcode6/Assimp.xcodeproj/xcshareddata/xcschemes/assimp.xcscheme b/workspaces/xcode6/Assimp.xcodeproj/xcshareddata/xcschemes/assimp.xcscheme index e74918baf..1786e9197 100644 --- a/workspaces/xcode6/Assimp.xcodeproj/xcshareddata/xcschemes/assimp.xcscheme +++ b/workspaces/xcode6/Assimp.xcodeproj/xcshareddata/xcschemes/assimp.xcscheme @@ -1,6 +1,6 @@ Date: Fri, 8 May 2015 17:50:31 -0700 Subject: [PATCH 10/51] - Turn off "-Wshorten-64-to-32" so we don't have TEN MILLION warnings when compiling with assimp. - Sure, it'd be better if this code were clean, but these warnings ONLY appear when we build for the simulator, NOT for iOS or OS X for real, so f' em. --- .../xcode6/Assimp.xcodeproj/project.pbxproj | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/workspaces/xcode6/Assimp.xcodeproj/project.pbxproj b/workspaces/xcode6/Assimp.xcodeproj/project.pbxproj index 7773fe7bb..918e4a665 100644 --- a/workspaces/xcode6/Assimp.xcodeproj/project.pbxproj +++ b/workspaces/xcode6/Assimp.xcodeproj/project.pbxproj @@ -1687,16 +1687,16 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LANGUAGE_STANDARD = "c++98"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = NO; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = NO; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COMBINE_HIDPI_IMAGES = YES; @@ -1718,6 +1718,7 @@ "$(inherited)", ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = NO; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.3; @@ -1734,16 +1735,16 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LANGUAGE_STANDARD = "c++98"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = NO; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = NO; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COMBINE_HIDPI_IMAGES = YES; @@ -1764,6 +1765,7 @@ ASSIMP_BUILD_DLL_EXPORT, "$(inherited)", ); + GCC_WARN_64_TO_32_BIT_CONVERSION = NO; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.3; @@ -1780,16 +1782,16 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LANGUAGE_STANDARD = "c++98"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = NO; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = NO; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COMBINE_HIDPI_IMAGES = YES; @@ -1809,6 +1811,7 @@ ASSIMP_BUILD_DLL_EXPORT, "$(inherited)", ); + GCC_WARN_64_TO_32_BIT_CONVERSION = NO; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.3; @@ -1825,16 +1828,16 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LANGUAGE_STANDARD = "c++98"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = NO; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = NO; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COMBINE_HIDPI_IMAGES = YES; @@ -1854,6 +1857,7 @@ ASSIMP_BUILD_DLL_EXPORT, "$(inherited)", ); + GCC_WARN_64_TO_32_BIT_CONVERSION = NO; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.3; From d1f36bf947b5a83eeff681f832e12f21fed7dca7 Mon Sep 17 00:00:00 2001 From: Wil Shipley Date: Tue, 12 May 2015 16:10:09 -0700 Subject: [PATCH 11/51] - Removed '/Users/wjs' from a path (that snuck in). --- workspaces/xcode6/Assimp.xcodeproj/project.pbxproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workspaces/xcode6/Assimp.xcodeproj/project.pbxproj b/workspaces/xcode6/Assimp.xcodeproj/project.pbxproj index 918e4a665..dd57d6566 100644 --- a/workspaces/xcode6/Assimp.xcodeproj/project.pbxproj +++ b/workspaces/xcode6/Assimp.xcodeproj/project.pbxproj @@ -362,7 +362,7 @@ 7DC4B0B5E57F4F4892CC823E /* MemoryIOWrapper.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = MemoryIOWrapper.h; path = code/MemoryIOWrapper.h; sourceTree = SOURCE_ROOT; }; 7E8BA0D338C9433587BC6C35 /* StreamWriter.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = StreamWriter.h; path = code/StreamWriter.h; sourceTree = SOURCE_ROOT; }; 7F29EF981AB26C4900E9D380 /* libz.1.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.1.dylib; path = /usr/lib/libz.1.dylib; sourceTree = ""; }; - 7F392D921AB2C7BB00D952EB /* libc++.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libc++.dylib"; path = "/Users/wjs/Source/UberDwelling/Dwelling Test Apps/Dwelling2DBakeTest/../../../../../../usr/lib/libc++.dylib"; sourceTree = ""; }; + 7F392D921AB2C7BB00D952EB /* libc++.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libc++.dylib"; path = "/usr/lib/libc++.dylib"; sourceTree = ""; }; 7F7922801AB43AC3005A8E5D /* libassimp.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libassimp.a; sourceTree = BUILT_PRODUCTS_DIR; }; 7FF72CB6E99E40E19AE0E64C /* MaterialSystem.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = MaterialSystem.cpp; path = code/MaterialSystem.cpp; sourceTree = SOURCE_ROOT; }; 815702BED5644DD5B242F347 /* TerragenLoader.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = TerragenLoader.h; path = code/TerragenLoader.h; sourceTree = SOURCE_ROOT; }; From 91ca983d5f6649d6144e3ebbd6d835594be490d2 Mon Sep 17 00:00:00 2001 From: Wil Shipley Date: Sun, 17 May 2015 18:36:17 -0700 Subject: [PATCH 12/51] - Workaround for Collada exporter in SketchUp 15.3.331 (possibly others) where it'll export the wrong "count" when exporting "lines". - When I encounter this condition I just print a warning and use the actual number of points in the file instead of the number they give, as opposed to throwing an exception and bailing on the whole file. - For an example of this kind of file see https://3dwarehouse.sketchup.com/warehouse/getpubliccontent?contentId=e4587719-2609-49ed-a2f6-20b98d1215f3&fn=Kartell-GE.zip - Some people have complained about this on http://forums.sketchup.com/t/bug-in-lines-exported-at-collada-format/8145 --- code/ColladaParser.cpp | 30 ++++++++++++++++++++++++++---- code/ColladaParser.h | 1 + 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/code/ColladaParser.cpp b/code/ColladaParser.cpp index dc177744f..653e8f2b1 100644 --- a/code/ColladaParser.cpp +++ b/code/ColladaParser.cpp @@ -1983,7 +1983,8 @@ void ColladaParser::ReadIndexData( Mesh* pMesh) } // small sanity check - if (primType != Prim_TriFans && primType != Prim_TriStrips) + if (primType != Prim_TriFans && primType != Prim_TriStrips && + primType != Prim_Lines) // this is ONLY to workaround a bug in SketchUp 15.3.331 where it writes the wrong 'count' when it writes out the 'lines'. ai_assert(actualPrimitives == numPrimitives); // only when we're done reading all

tags (and thus know the final vertex count) can we commit the submesh @@ -2091,9 +2092,15 @@ size_t ColladaParser::ReadPrimitives( Mesh* pMesh, std::vector& pP } // complain if the index count doesn't fit - if( expectedPointCount > 0 && indices.size() != expectedPointCount * numOffsets) - ThrowException( "Expected different index count in

element."); - else if( expectedPointCount == 0 && (indices.size() % numOffsets) != 0) + if( expectedPointCount > 0 && indices.size() != expectedPointCount * numOffsets) { + if (pPrimType == Prim_Lines) { + // HACK: We just fix this number since SketchUp 15.3.331 writes the wrong 'count' for 'lines' + ReportWarning( "Expected different index count in

element, %d instead of %d.", indices.size(), expectedPointCount * numOffsets); + pNumPrimitives = (indices.size() / numOffsets) / 2; + } else + ThrowException( "Expected different index count in

element."); + + } else if( expectedPointCount == 0 && (indices.size() % numOffsets) != 0) ThrowException( "Expected different index count in

element."); // find the data for all sources @@ -2696,6 +2703,21 @@ AI_WONT_RETURN void ColladaParser::ThrowException( const std::string& pError) co throw DeadlyImportError( boost::str( boost::format( "Collada: %s - %s") % mFileName % pError)); } +void ColladaParser::ReportWarning(const char* msg,...) +{ + ai_assert(NULL != msg); + + va_list args; + va_start(args,msg); + + char szBuffer[3000]; + const int iLen = vsprintf(szBuffer,msg,args); + ai_assert(iLen > 0); + + va_end(args); + DefaultLogger::get()->warn("Validation warning: " + std::string(szBuffer,iLen)); +} + // ------------------------------------------------------------------------------------------------ // Skips all data until the end node of the current element void ColladaParser::SkipElement() diff --git a/code/ColladaParser.h b/code/ColladaParser.h index 553f9caf4..327d2d032 100644 --- a/code/ColladaParser.h +++ b/code/ColladaParser.h @@ -213,6 +213,7 @@ protected: protected: /** Aborts the file reading with an exception */ AI_WONT_RETURN void ThrowException( const std::string& pError) const AI_WONT_RETURN_SUFFIX; + void ReportWarning(const char* msg,...); /** Skips all data until the end node of the current element */ void SkipElement(); From b581ae9c3d4d82a0481437653eed77b2913e7753 Mon Sep 17 00:00:00 2001 From: Wil Shipley Date: Fri, 12 Jun 2015 16:12:36 -0700 Subject: [PATCH 13/51] - Opened in latest Xcode. --- .../Assimp.xcodeproj/xcshareddata/xcschemes/assimp.xcscheme | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/workspaces/xcode6/Assimp.xcodeproj/xcshareddata/xcschemes/assimp.xcscheme b/workspaces/xcode6/Assimp.xcodeproj/xcshareddata/xcschemes/assimp.xcscheme index 1786e9197..fdaa14d82 100644 --- a/workspaces/xcode6/Assimp.xcodeproj/xcshareddata/xcschemes/assimp.xcscheme +++ b/workspaces/xcode6/Assimp.xcodeproj/xcshareddata/xcschemes/assimp.xcscheme @@ -1,6 +1,6 @@ + + Date: Sun, 14 Jun 2015 18:09:03 -0700 Subject: [PATCH 14/51] - iOS target 9.0 --- workspaces/xcode6/Assimp.xcodeproj/project.pbxproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/workspaces/xcode6/Assimp.xcodeproj/project.pbxproj b/workspaces/xcode6/Assimp.xcodeproj/project.pbxproj index dd57d6566..4dba141b2 100644 --- a/workspaces/xcode6/Assimp.xcodeproj/project.pbxproj +++ b/workspaces/xcode6/Assimp.xcodeproj/project.pbxproj @@ -1721,7 +1721,7 @@ GCC_WARN_64_TO_32_BIT_CONVERSION = NO; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.3; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = "-ObjC"; @@ -1768,7 +1768,7 @@ GCC_WARN_64_TO_32_BIT_CONVERSION = NO; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.3; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = NO; OTHER_LDFLAGS = "-ObjC"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -1814,7 +1814,7 @@ GCC_WARN_64_TO_32_BIT_CONVERSION = NO; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.3; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = NO; OTHER_LDFLAGS = "-ObjC"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -1860,7 +1860,7 @@ GCC_WARN_64_TO_32_BIT_CONVERSION = NO; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.3; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = NO; OTHER_LDFLAGS = "-ObjC"; PRODUCT_NAME = "$(TARGET_NAME)"; From 5c00aef7cd8ab6b7f86c8297958a630f9459dc53 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Fri, 17 Jul 2015 20:03:23 +0200 Subject: [PATCH 15/51] iOpenGEX: use std::string for grammar::token. --- code/OpenGEXImporter.cpp | 78 +++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 45 deletions(-) diff --git a/code/OpenGEXImporter.cpp b/code/OpenGEXImporter.cpp index 137a8c1e5..f260cc772 100644 --- a/code/OpenGEXImporter.cpp +++ b/code/OpenGEXImporter.cpp @@ -63,23 +63,23 @@ static const aiImporterDesc desc = { }; namespace Grammar { - static const char *MetricType = "Metric"; - static const char *Metric_DistanceType = "distance"; - static const char *Metric_AngleType = "angle"; - static const char *Metric_TimeType = "time"; - static const char *Metric_UpType = "up"; - static const char *NameType = "Name"; - static const char *ObjectRefType = "ObjectRef"; - static const char *MaterialRefType = "MaterialRef"; - static const char *MetricKeyType = "key"; - static const char *GeometryNodeType = "GeometryNode"; - static const char *GeometryObjectType = "GeometryObject"; - static const char *TransformType = "Transform"; - static const char *MeshType = "Mesh"; - static const char *VertexArrayType = "VertexArray"; - static const char *IndexArrayType = "IndexArray"; - static const char *MaterialType = "Material"; - static const char *ColorType = "Color"; + static const std::string MetricType = "Metric"; + static const std::string Metric_DistanceType = "distance"; + static const std::string Metric_AngleType = "angle"; + static const std::string Metric_TimeType = "time"; + static const std::string Metric_UpType = "up"; + static const std::string NameType = "Name"; + static const std::string ObjectRefType = "ObjectRef"; + static const std::string MaterialRefType = "MaterialRef"; + static const std::string MetricKeyType = "key"; + static const std::string GeometryNodeType = "GeometryNode"; + static const std::string GeometryObjectType = "GeometryObject"; + static const std::string TransformType = "Transform"; + static const std::string MeshType = "Mesh"; + static const std::string VertexArrayType = "VertexArray"; + static const std::string IndexArrayType = "IndexArray"; + static const std::string MaterialType = "Material"; + static const std::string ColorType = "Color"; static const std::string DiffuseColorToken = "diffuse"; static const std::string SpecularColorToken = "specular"; static const std::string EmissionColorToken = "emission"; @@ -112,7 +112,7 @@ namespace Grammar { TextureToken }; - static const char *ValidMetricToken[ 4 ] = { + static const std::string ValidMetricToken[ 4 ] = { Metric_DistanceType, Metric_AngleType, Metric_TimeType, @@ -126,7 +126,7 @@ namespace Grammar { int idx( -1 ); for( size_t i = 0; i < 4; i++ ) { - if( 0 == strncmp( ValidMetricToken[ i ], token, strlen( token ) ) ) { + if( ValidMetricToken[ i ] == token ) { idx = (int) i; break; } @@ -136,45 +136,33 @@ namespace Grammar { } static TokenType matchTokenType( const char *tokenType ) { - if( 0 == strncmp( MetricType, tokenType, strlen( MetricType ) ) ) { + if( MetricType == tokenType ) { return MetricToken; - } else if( 0 == strncmp( NameType, tokenType, strlen( NameType ) ) ) { + } else if( NameType == tokenType ) { return NameToken; - } - else if( 0 == strncmp( ObjectRefType, tokenType, strlen( ObjectRefType ) ) ) { + } else if( ObjectRefType == tokenType ) { return ObjectRefToken; - } - else if( 0 == strncmp( MaterialRefType, tokenType, strlen( MaterialRefType ) ) ) { + } else if( MaterialRefType == tokenType ) { return MaterialRefToken; - } - else if( 0 == strncmp( MetricKeyType, tokenType, strlen( MetricKeyType ) ) ) { + } else if( MetricKeyType == tokenType ) { return MetricKeyToken; - } - else if( 0 == strncmp( GeometryNodeType, tokenType, strlen( GeometryNodeType ) ) ) { + } else if( GeometryNodeType == tokenType ) { return GeometryNodeToken; - } - else if( 0 == strncmp( GeometryObjectType, tokenType, strlen( GeometryObjectType ) ) ) { + } else if( GeometryObjectType == tokenType ) { return GeometryObjectToken; - } - else if( 0 == strncmp( TransformType, tokenType, strlen( TransformType ) ) ) { + } else if( TransformType == tokenType ) { return TransformToken; - } - else if( 0 == strncmp( MeshType, tokenType, strlen( MeshType ) ) ) { + } else if( MeshType == tokenType ) { return MeshToken; - } - else if( 0 == strncmp( VertexArrayType, tokenType, strlen( VertexArrayType ) ) ) { + } else if( VertexArrayType == tokenType ) { return VertexArrayToken; - } - else if( 0 == strncmp( IndexArrayType, tokenType, strlen( IndexArrayType ) ) ) { + } else if( IndexArrayType == tokenType ) { return IndexArrayToken; - } - else if( 0 == strncmp( MaterialType, tokenType, strlen( MaterialType ) ) ) { + } else if( MaterialType == tokenType ) { return MaterialToken; - } - else if( 0 == strncmp( ColorType, tokenType, strlen( ColorType ) ) ) { + } else if( ColorType == tokenType ) { return ColorToken; - } - else if( 0 == strncmp( TextureType, tokenType, strlen( TextureType ) ) ) { + } else if( TextureType == tokenType ) { return TextureToken; } From bcb0ca3efaf79748ce2b422f89dbaceb4ce2a404 Mon Sep 17 00:00:00 2001 From: Brian Schwind Date: Mon, 20 Jul 2015 22:02:48 -0400 Subject: [PATCH 16/51] Include correct headers, fix string length bug - AssimpPCH.h appears to have been removed in #536 - There was a bug where if your model data had a null terminator, AndroidJNIIOSystem would incorrectly calculate the number of bytes it needed to write to the file (since it reads a compressed file from the Android assets, and then writes it to the internalDataPath directory for later importing) --- port/AndroidJNI/AndroidJNIIOSystem.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/port/AndroidJNI/AndroidJNIIOSystem.cpp b/port/AndroidJNI/AndroidJNIIOSystem.cpp index 4e8f19187..4a149e050 100644 --- a/port/AndroidJNI/AndroidJNIIOSystem.cpp +++ b/port/AndroidJNI/AndroidJNIIOSystem.cpp @@ -42,7 +42,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /** @file Android extension of DefaultIOSystem using the standard C file functions */ -#include +#include +#include #if __ANDROID__ and __ANDROID_API__ > 9 and defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT) #include @@ -50,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include #include #include #include @@ -114,7 +116,7 @@ bool AndroidJNIIOSystem::AndroidExtractAsset(std::string name) // Open file AAsset* asset = AAssetManager_open(mApkAssetManager, name.c_str(), AASSET_MODE_UNKNOWN); - std::string assetContent; + std::vector assetContent; if (asset != NULL) { // Find size @@ -138,7 +140,7 @@ bool AndroidJNIIOSystem::AndroidExtractAsset(std::string name) } // Write output buffer into a file - assetExtracted.write(assetContent.c_str(), strlen(assetContent.c_str())); + assetExtracted.write(&assetContent[0], assetContent.size()); assetExtracted.close(); __android_log_print(ANDROID_LOG_DEFAULT, "Assimp", "Asset extracted"); From f7a8c80fc2fd3693392370dcfd75ba75c4a62ee6 Mon Sep 17 00:00:00 2001 From: Wil Shipley Date: Sun, 26 Jul 2015 19:35:14 -0700 Subject: [PATCH 17/51] - Previous merge accidentally copied OpenDDL C++ files into include directory. --- .../include/openddlparser/DDLNode.cpp | 209 ---- .../include/openddlparser/OpenDDLParser.cpp | 907 ------------------ .../include/openddlparser/Value.cpp | 336 ------- .../xcode6/Assimp.xcodeproj/project.pbxproj | 28 +- 4 files changed, 14 insertions(+), 1466 deletions(-) delete mode 100644 contrib/openddlparser/include/openddlparser/DDLNode.cpp delete mode 100644 contrib/openddlparser/include/openddlparser/OpenDDLParser.cpp delete mode 100644 contrib/openddlparser/include/openddlparser/Value.cpp diff --git a/contrib/openddlparser/include/openddlparser/DDLNode.cpp b/contrib/openddlparser/include/openddlparser/DDLNode.cpp deleted file mode 100644 index 5d3fd03f9..000000000 --- a/contrib/openddlparser/include/openddlparser/DDLNode.cpp +++ /dev/null @@ -1,209 +0,0 @@ -/*----------------------------------------------------------------------------------------------- -The MIT License (MIT) - -Copyright (c) 2014-2015 Kim Kulling - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ------------------------------------------------------------------------------------------------*/ -#include -#include - -#include - -BEGIN_ODDLPARSER_NS - -DDLNode::DllNodeList DDLNode::s_allocatedNodes; - -template -inline -static void releaseDataType( T *ptr ) { - if( ddl_nullptr == ptr ) { - return; - } - - T *current( ddl_nullptr ); - while( ptr ) { - current = ptr; - ptr = ptr->m_next; - delete current; - } -} - -static void releaseReferencedNames( Reference *ref ) { - if( ddl_nullptr == ref ) { - return; - } - - if( ref->m_referencedName ) { - for( size_t i = 0; i < ref->m_numRefs; i++ ) { - delete ref->m_referencedName; - } - } -} - -DDLNode::DDLNode( const std::string &type, const std::string &name, size_t idx, DDLNode *parent ) -: m_type( type ) -, m_name( name ) -, m_parent( parent ) -, m_children() -, m_properties( ddl_nullptr ) -, m_value( ddl_nullptr ) -, m_dtArrayList( ddl_nullptr ) -, m_references( ddl_nullptr ) -, m_idx( idx ) { - if( m_parent ) { - m_parent->m_children.push_back( this ); - } -} - -DDLNode::~DDLNode() { - releaseDataType( m_properties ); - releaseDataType( m_value ); - releaseReferencedNames( m_references ); - - delete m_dtArrayList; - m_dtArrayList = ddl_nullptr; - if( s_allocatedNodes[ m_idx ] == this ) { - s_allocatedNodes[ m_idx ] = ddl_nullptr; - } -} - -void DDLNode::attachParent( DDLNode *parent ) { - if( m_parent == parent ) { - return; - } - - m_parent = parent; - if( ddl_nullptr != m_parent ) { - m_parent->m_children.push_back( this ); - } -} - -void DDLNode::detachParent() { - if( m_parent ) { - std::vector::iterator it; - it = std::find( m_parent->m_children.begin(), m_parent->m_children.end(), this ); - if( m_parent->m_children.end() != it ) { - m_parent->m_children.erase( it ); - } - m_parent = ddl_nullptr; - } -} - -DDLNode *DDLNode::getParent() const { - return m_parent; -} - -const DDLNode::DllNodeList &DDLNode::getChildNodeList() const { - return m_children; -} - -void DDLNode::setType( const std::string &type ) { - m_type = type; -} - -const std::string &DDLNode::getType() const { - return m_type; -} - - -void DDLNode::setName( const std::string &name ) { - m_name = name; -} - -const std::string &DDLNode::getName() const { - return m_name; -} - -void DDLNode::setProperties( Property *prop ) { - m_properties = prop; -} - -Property *DDLNode::getProperties() const { - return m_properties; -} - -bool DDLNode::hasProperty( const std::string &name ) { - const Property *prop( findPropertyByName( name ) ); - return ( ddl_nullptr != prop ); -} - -Property *DDLNode::findPropertyByName( const std::string &name ) { - if( name.empty() ) { - return ddl_nullptr; - } - - if( ddl_nullptr == m_properties ) { - return ddl_nullptr; - } - Property *current( m_properties ); - while( ddl_nullptr != current ) { - int res = strncmp( current->m_key->m_text.m_buffer, name.c_str(), name.size() ); - if( 0 == res ) { - return current; - } - current = current->m_next; - } - - return ddl_nullptr; -} - -void DDLNode::setValue( Value *val ) { - m_value = val; -} - -Value *DDLNode::getValue() const { - return m_value; -} - -void DDLNode::setDataArrayList( DataArrayList *dtArrayList ) { - m_dtArrayList = dtArrayList; -} - -DataArrayList *DDLNode::getDataArrayList() const { - return m_dtArrayList; -} - -void DDLNode::setReferences( Reference *refs ) { - m_references = refs; -} - -Reference *DDLNode::getReferences() const { - return m_references; -} - -DDLNode *DDLNode::create( const std::string &type, const std::string &name, DDLNode *parent ) { - const size_t idx( s_allocatedNodes.size() ); - DDLNode *node = new DDLNode( type, name, idx, parent ); - s_allocatedNodes.push_back( node ); - - return node; -} - -void DDLNode::releaseNodes() { - if( s_allocatedNodes.size() > 0 ) { - for( DllNodeList::iterator it = s_allocatedNodes.begin(); it != s_allocatedNodes.end(); it++ ) { - if( *it ) { - delete *it; - } - } - s_allocatedNodes.clear(); - } -} - -END_ODDLPARSER_NS diff --git a/contrib/openddlparser/include/openddlparser/OpenDDLParser.cpp b/contrib/openddlparser/include/openddlparser/OpenDDLParser.cpp deleted file mode 100644 index 77a1c4a25..000000000 --- a/contrib/openddlparser/include/openddlparser/OpenDDLParser.cpp +++ /dev/null @@ -1,907 +0,0 @@ -/*----------------------------------------------------------------------------------------------- -The MIT License (MIT) - -Copyright (c) 2014-2015 Kim Kulling - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ------------------------------------------------------------------------------------------------*/ -#include - -#include -#include -#include -#include -#include - -#ifdef _WIN32 -# include -#endif // _WIN32 - -#define DEBUG_HEADER_NAME - -BEGIN_ODDLPARSER_NS - -static const char *Version = "0.1.0"; - -namespace Grammar { - static const char * const OpenBracketToken = "{"; - static const char * const CloseBracketToken = "}"; - static const char * const OpenPropertyToken = "("; - static const char * const ClosePropertyToken = ")"; - static const char * const BoolTrue = "true"; - static const char * const BoolFalse = "false"; - static const char * const RefToken = "ref"; - static const char * const CommaSeparator = ","; - - static const char* PrimitiveTypeToken[ Value::ddl_types_max ] = { - "bool", - "int8", - "int16", - "int32", - "int64", - "unsigned_int8", - "unsigned_int16", - "unsigned_int32", - "unsigned_int64", - "half", - "float", - "double", - "string", - "ref" - }; -} // Namespace Grammar - - -static void logInvalidTokenError( char *in, const std::string &exp, OpenDDLParser::logCallback callback ) { - std::stringstream stream; - stream << "Invalid token " << *in << ", " << exp << " expected." << std::endl; - callback( ddl_error_msg, stream.str() ); -} - -static bool isIntegerType( Value::ValueType integerType ) { - if( integerType != Value::ddl_int8 && integerType != Value::ddl_int16 && - integerType != Value::ddl_int32 && integerType != Value::ddl_int64 ) { - return false; - } - - return true; -} - -static DDLNode *createDDLNode( Identifier *id, OpenDDLParser *parser ) { - if( ddl_nullptr == id || ddl_nullptr == parser ) { - return ddl_nullptr; - } - - const std::string type( id->m_text.m_buffer ); - DDLNode *parent( parser->top() ); - DDLNode *node = DDLNode::create( type, "", parent ); - - return node; -} - -static void logMessage( LogSeverity severity, const std::string &msg ) { - std::string log; - if( ddl_debug_msg == severity ) { - log += "Debug:"; - } else if( ddl_info_msg == severity ) { - log += "Info :"; - } else if( ddl_warn_msg == severity ) { - log += "Warn :"; - } else if( ddl_error_msg == severity ) { - log += "Error:"; - } else { - log += "None :"; - } - - log += msg; - std::cout << log; -} - -OpenDDLParser::OpenDDLParser() -: m_logCallback( logMessage ) -, m_buffer() -, m_stack() -, m_context( ddl_nullptr ) { - // empty -} - -OpenDDLParser::OpenDDLParser( char *buffer, size_t len ) -: m_logCallback( &logMessage ) -, m_buffer() -, m_context( ddl_nullptr ) { - if( 0 != len ) { - setBuffer( buffer, len ); - } -} - -OpenDDLParser::~OpenDDLParser() { - clear(); -} - -void OpenDDLParser::setLogCallback( logCallback callback ) { - if( ddl_nullptr != callback ) { - // install user-specific log callback - m_logCallback = callback; - } else { - // install default log callback - m_logCallback = &logMessage; - } -} - -OpenDDLParser::logCallback OpenDDLParser::getLogCallback() const { - return m_logCallback; -} - -void OpenDDLParser::setBuffer( char *buffer, size_t len ) { - clear(); - if( 0 == len ) { - return; - } - - m_buffer.resize( len ); - ::memcpy(&m_buffer[ 0 ], buffer, len ); -} - -void OpenDDLParser::setBuffer( const std::vector &buffer ) { - clear(); - m_buffer.resize( buffer.size() ); - std::copy( buffer.begin(), buffer.end(), m_buffer.begin() ); -} - -const char *OpenDDLParser::getBuffer() const { - if( m_buffer.empty() ) { - return ddl_nullptr; - } - - return &m_buffer[ 0 ]; -} - -size_t OpenDDLParser::getBufferSize() const { - return m_buffer.size(); -} - -void OpenDDLParser::clear() { - m_buffer.resize( 0 ); - if( m_context ) { - m_context->m_root = ddl_nullptr; - } - - DDLNode::releaseNodes(); -} - -bool OpenDDLParser::parse() { - if( m_buffer.empty() ) { - return false; - } - - normalizeBuffer( m_buffer ); - - m_context = new Context; - m_context->m_root = DDLNode::create( "root", "", ddl_nullptr ); - pushNode( m_context->m_root ); - - // do the main parsing - char *current( &m_buffer[ 0 ] ); - char *end( &m_buffer[ m_buffer.size() - 1 ] + 1 ); - size_t pos( current - &m_buffer[ 0 ] ); - while( pos < m_buffer.size() ) { - current = parseNextNode( current, end ); - pos = current - &m_buffer[ 0 ]; - } - return true; -} - -char *OpenDDLParser::parseNextNode( char *in, char *end ) { - in = parseHeader( in, end ); - in = parseStructure( in, end ); - - return in; -} - -static void dumpId( Identifier *id ) { - if( ddl_nullptr != id ) { - std::cout << id->m_text.m_buffer << std::endl; - } -} - -char *OpenDDLParser::parseHeader( char *in, char *end ) { - if( ddl_nullptr == in || in == end ) { - return in; - } - - Identifier *id( ddl_nullptr ); - in = OpenDDLParser::parseIdentifier( in, end, &id ); - -#ifdef DEBUG_HEADER_NAME - dumpId( id ); -#endif // DEBUG_HEADER_NAME - - in = lookForNextToken( in, end ); - Property *first( ddl_nullptr ); - if( ddl_nullptr != id ) { - if( *in == '(' ) { - in++; - Property *prop( ddl_nullptr ), *prev( ddl_nullptr ); - while( *in != ')' && in != end ) { - in = OpenDDLParser::parseProperty( in, end, &prop ); - in = lookForNextToken( in, end ); - - if( *in != ',' && *in != ')' ) { - logInvalidTokenError( in, ")", m_logCallback ); - return in; - } - - if( ddl_nullptr != prop && *in != ',' ) { - if( ddl_nullptr == first ) { - first = prop; - } - if( ddl_nullptr != prev ) { - prev->m_next = prop; - } - prev = prop; - } - } - in++; - } - - // store the node - DDLNode *node( createDDLNode( id, this ) ); - if( ddl_nullptr != node ) { - pushNode( node ); - } else { - std::cerr << "nullptr returned by creating DDLNode." << std::endl; - } - - // set the properties - if( ddl_nullptr != first ) { - node->setProperties( first ); - } - - Name *name( ddl_nullptr ); - in = OpenDDLParser::parseName( in, end, &name ); - if( ddl_nullptr != name ) { - const std::string nodeName( name->m_id->m_text.m_buffer ); - node->setName( nodeName ); - } - } - - return in; -} - -char *OpenDDLParser::parseStructure( char *in, char *end ) { - if( ddl_nullptr == in || in == end ) { - return in; - } - - bool error( false ); - in = lookForNextToken( in, end ); - if( *in == '{' ) { - // loop over all children ( data and nodes ) - do { - in = parseStructureBody( in, end, error ); - } while ( *in != '}' ); - in++; - } else { - in++; - logInvalidTokenError( in, std::string( Grammar::OpenBracketToken ), m_logCallback ); - error = true; - return in; - } - in = lookForNextToken( in, end ); - - // pop node from stack after successful parsing - if( !error ) { - popNode(); - } - - return in; -} - -static void setNodeValues( DDLNode *currentNode, Value *values ) { - if( ddl_nullptr != values ){ - if( ddl_nullptr != currentNode ) { - currentNode->setValue( values ); - } - } -} - -static void setNodeReferences( DDLNode *currentNode, Reference *refs ) { - if( ddl_nullptr != refs ) { - if( ddl_nullptr != currentNode ) { - currentNode->setReferences( refs ); - } - } -} - -static void setNodeDataArrayList( DDLNode *currentNode, DataArrayList *dtArrayList ) { - if( ddl_nullptr != dtArrayList ) { - if( ddl_nullptr != currentNode ) { - currentNode->setDataArrayList( dtArrayList ); - } - } -} - -char *OpenDDLParser::parseStructureBody( char *in, char *end, bool &error ) { - if( !isNumeric( *in ) && !isCharacter( *in ) ) { - in++; - } - - in = lookForNextToken( in, end ); - Value::ValueType type( Value::ddl_none ); - size_t arrayLen( 0 ); - in = OpenDDLParser::parsePrimitiveDataType( in, end, type, arrayLen ); - if( Value::ddl_none != type ) { - // parse a primitive data type - in = lookForNextToken( in, end ); - if( *in == '{' ) { - Reference *refs( ddl_nullptr ); - DataArrayList *dtArrayList( ddl_nullptr ); - Value *values( ddl_nullptr ); - if( 1 == arrayLen ) { - size_t numRefs( 0 ), numValues( 0 ); - in = parseDataList( in, end, &values, numValues, &refs, numRefs ); - setNodeValues( top(), values ); - setNodeReferences( top(), refs ); - } else if( arrayLen > 1 ) { - in = parseDataArrayList( in, end, &dtArrayList ); - setNodeDataArrayList( top(), dtArrayList ); - } else { - std::cerr << "0 for array is invalid." << std::endl; - error = true; - } - } - - in = lookForNextToken( in, end ); - if( *in != '}' ) { - logInvalidTokenError( in, std::string( Grammar::CloseBracketToken ), m_logCallback ); - } else { - //in++; - } - } else { - // parse a complex data type - in = parseNextNode( in, end ); - } - - return in; -} - -void OpenDDLParser::pushNode( DDLNode *node ) { - if( ddl_nullptr == node ) { - return; - } - - m_stack.push_back( node ); -} - -DDLNode *OpenDDLParser::popNode() { - if( m_stack.empty() ) { - return ddl_nullptr; - } - - DDLNode *topNode( top() ); - m_stack.pop_back(); - - return topNode; -} - -DDLNode *OpenDDLParser::top() { - if( m_stack.empty() ) { - return ddl_nullptr; - } - - DDLNode *top( m_stack.back() ); - return top; -} - -DDLNode *OpenDDLParser::getRoot() const { - if( ddl_nullptr == m_context ) { - return ddl_nullptr; - } - - return m_context->m_root; -} - -Context *OpenDDLParser::getContext() const { - return m_context; -} - -void OpenDDLParser::normalizeBuffer( std::vector &buffer) { - if( buffer.empty() ) { - return; - } - - std::vector newBuffer; - const size_t len( buffer.size() ); - char *end( &buffer[ len-1 ] + 1 ); - for( size_t readIdx = 0; readIdx( c, end ) && !isNewLine( *c ) ) { - newBuffer.push_back( buffer[ readIdx ] ); - } else { - if( isComment( c, end ) ) { - readIdx++; - // skip the comment and the rest of the line - while( !isEndofLine( buffer[ readIdx ] ) ) { - readIdx++; - } - } - } - } - buffer = newBuffer; -} - -char *OpenDDLParser::parseName( char *in, char *end, Name **name ) { - *name = ddl_nullptr; - if( ddl_nullptr == in || in == end ) { - return in; - } - - // ignore blanks - in = lookForNextToken( in, end ); - if( *in != '$' && *in != '%' ) { - return in; - } - - NameType ntype( GlobalName ); - if( *in == '%' ) { - ntype = LocalName; - } - - Name *currentName( ddl_nullptr ); - Identifier *id( ddl_nullptr ); - in = parseIdentifier( in, end, &id ); - if( id ) { - currentName = new Name( ntype, id ); - if( currentName ) { - *name = currentName; - } - } - - return in; -} - -char *OpenDDLParser::parseIdentifier( char *in, char *end, Identifier **id ) { - *id = ddl_nullptr; - if( ddl_nullptr == in || in == end ) { - return in; - } - - // ignore blanks - in = lookForNextToken( in, end ); - - // staring with a number is forbidden - if( isNumeric( *in ) ) { - return in; - } - - // get size of id - size_t idLen( 0 ); - char *start( in ); - while( !isSeparator( *in ) && !isNewLine( *in ) && ( in != end ) && *in != '(' && *in != ')' ) { - in++; - idLen++; - } - - const size_t len( idLen ); - Identifier *newId = new Identifier( start, len ); - *id = newId; - - return in; -} - -char *OpenDDLParser::parsePrimitiveDataType( char *in, char *end, Value::ValueType &type, size_t &len ) { - type = Value::ddl_none; - len = 0; - if( ddl_nullptr == in || in == end ) { - return in; - } - - size_t prim_len( 0 ); - for( unsigned int i = 0; i < Value::ddl_types_max; i++ ) { - prim_len = strlen( Grammar::PrimitiveTypeToken[ i ] ); - if( 0 == strncmp( in, Grammar::PrimitiveTypeToken[ i ], prim_len ) ) { - type = ( Value::ValueType ) i; - break; - } - } - - if( Value::ddl_none == type ) { - in = lookForNextToken( in, end ); - return in; - } else { - in += prim_len; - } - - bool ok( true ); - if( *in == '[' ) { - ok = false; - in++; - char *start( in ); - while ( in != end ) { - in++; - if( *in == ']' ) { - len = atoi( start ); - ok = true; - in++; - break; - } - } - } else { - len = 1; - } - if( !ok ) { - type = Value::ddl_none; - } - - return in; -} - -char *OpenDDLParser::parseReference( char *in, char *end, std::vector &names ) { - if( ddl_nullptr == in || in == end ) { - return in; - } - - Name *nextName( ddl_nullptr ); - in = parseName( in, end, &nextName ); - if( nextName ) { - names.push_back( nextName ); - } - while( ',' == *in ) { - in = getNextSeparator( in, end ); - if( ',' == *in ) { - in = parseName( in, end, &nextName ); - if( nextName ) { - names.push_back( nextName ); - } - } else { - break; - } - } - - return in; -} - -char *OpenDDLParser::parseBooleanLiteral( char *in, char *end, Value **boolean ) { - *boolean = ddl_nullptr; - if( ddl_nullptr == in || in == end ) { - return in; - } - - in = lookForNextToken( in, end ); - char *start( in ); - size_t len( 0 ); - while( !isSeparator( *in ) && in != end ) { - in++; - len++; - } - len++; - int res = ::strncmp( Grammar::BoolTrue, start, strlen( Grammar::BoolTrue ) ); - if( 0 != res ) { - res = ::strncmp( Grammar::BoolFalse, start, strlen( Grammar::BoolFalse ) ); - if( 0 != res ) { - *boolean = ddl_nullptr; - return in; - } - *boolean = ValueAllocator::allocPrimData( Value::ddl_bool ); - (*boolean)->setBool( false ); - } else { - *boolean = ValueAllocator::allocPrimData( Value::ddl_bool ); - (*boolean)->setBool( true ); - } - - return in; -} - -char *OpenDDLParser::parseIntegerLiteral( char *in, char *end, Value **integer, Value::ValueType integerType ) { - *integer = ddl_nullptr; - if( ddl_nullptr == in || in == end ) { - return in; - } - - if( !isIntegerType( integerType ) ) { - return in; - } - - in = lookForNextToken( in, end ); - char *start( in ); - while( !isSeparator( *in ) && in != end ) { - in++; - } - - if( isNumeric( *start ) ) { - const int value( atoi( start ) ); - *integer = ValueAllocator::allocPrimData( integerType ); - switch( integerType ) { - case Value::ddl_int8: - ( *integer )->setInt8( (int8) value ); - break; - case Value::ddl_int16: - ( *integer )->setInt16( ( int16 ) value ); - break; - case Value::ddl_int32: - ( *integer )->setInt32( ( int32 ) value ); - break; - case Value::ddl_int64: - ( *integer )->setInt64( ( int64 ) value ); - break; - default: - break; - } - } - - return in; -} - -char *OpenDDLParser::parseFloatingLiteral( char *in, char *end, Value **floating ) { - *floating = ddl_nullptr; - if( ddl_nullptr == in || in == end ) { - return in; - } - - in = lookForNextToken( in, end ); - char *start( in ); - while( !isSeparator( *in ) && in != end ) { - in++; - } - - // parse the float value - bool ok( false ); - if( isNumeric( *start ) ) { - ok = true; - } else { - if( *start == '-' ) { - if( isNumeric( *(start+1) ) ) { - ok = true; - } - } - } - - if( ok ) { - const float value( ( float ) atof( start ) ); - *floating = ValueAllocator::allocPrimData( Value::ddl_float ); - ( *floating )->setFloat( value ); - } - - return in; -} - -char *OpenDDLParser::parseStringLiteral( char *in, char *end, Value **stringData ) { - *stringData = ddl_nullptr; - if( ddl_nullptr == in || in == end ) { - return in; - } - - in = lookForNextToken( in, end ); - size_t len( 0 ); - char *start( in ); - if( *start == '\"' ) { - start++; - in++; - while( *in != '\"' && in != end ) { - in++; - len++; - } - - *stringData = ValueAllocator::allocPrimData( Value::ddl_string, len ); - ::strncpy( ( char* ) ( *stringData )->m_data, start, len ); - ( *stringData )->m_data[len] = '\0'; - in++; - } - - return in; -} - -static void createPropertyWithData( Identifier *id, Value *primData, Property **prop ) { - if( ddl_nullptr != primData ) { - ( *prop ) = new Property( id ); - ( *prop )->m_value = primData; - } -} - -char *OpenDDLParser::parseHexaLiteral( char *in, char *end, Value **data ) { - *data = ddl_nullptr; - if( ddl_nullptr == in || in == end ) { - return in; - } - - in = lookForNextToken( in, end ); - if( *in != '0' ) { - return in; - } - - in++; - if( *in != 'x' && *in != 'X' ) { - return in; - } - - in++; - bool ok( true ); - char *start( in ); - int pos( 0 ); - while( !isSeparator( *in ) && in != end ) { - if( ( *in < '0' && *in > '9' ) || ( *in < 'a' && *in > 'f' ) || ( *in < 'A' && *in > 'F' ) ) { - ok = false; - break; - } - pos++; - in++; - } - - if( !ok ) { - return in; - } - - int value( 0 ); - while( pos > 0 ) { - int v = hex2Decimal( *start ); - pos--; - value = ( value << 4 ) | v; - start++; - } - - *data = ValueAllocator::allocPrimData( Value::ddl_unsigned_int64 ); - if( ddl_nullptr != *data ) { - ( *data )->setUnsignedInt64( value ); - } - - return in; -} - -char *OpenDDLParser::parseProperty( char *in, char *end, Property **prop ) { - *prop = ddl_nullptr; - if( ddl_nullptr == in || in == end ) { - return in; - } - - in = lookForNextToken( in, end ); - Identifier *id( ddl_nullptr ); - in = parseIdentifier( in, end, &id ); - if( ddl_nullptr != id ) { - in = lookForNextToken( in, end ); - if( *in == '=' ) { - in++; - in = getNextToken( in, end ); - Value *primData( ddl_nullptr ); - if( isInteger( in, end ) ) { - in = parseIntegerLiteral( in, end, &primData ); - createPropertyWithData( id, primData, prop ); - } else if( isFloat( in, end ) ) { - in = parseFloatingLiteral( in, end, &primData ); - createPropertyWithData( id, primData, prop ); - } else if( isStringLiteral( *in ) ) { // string data - in = parseStringLiteral( in, end, &primData ); - createPropertyWithData( id, primData, prop ); - } else { // reference data - std::vector names; - in = parseReference( in, end, names ); - if( !names.empty() ) { - Reference *ref = new Reference( names.size(), &names[ 0 ] ); - ( *prop ) = new Property( id ); - ( *prop )->m_ref = ref; - } - } - } - } - - return in; -} - -char *OpenDDLParser::parseDataList( char *in, char *end, Value **data, size_t &numValues, Reference **refs, size_t &numRefs ) { - *data = ddl_nullptr; - numValues = numRefs = 0; - if( ddl_nullptr == in || in == end ) { - return in; - } - - in = lookForNextToken( in, end ); - if( *in == '{' ) { - in++; - Value *current( ddl_nullptr ), *prev( ddl_nullptr ); - while( '}' != *in ) { - current = ddl_nullptr; - in = lookForNextToken( in, end ); - if( isInteger( in, end ) ) { - in = parseIntegerLiteral( in, end, ¤t ); - } else if( isFloat( in, end ) ) { - in = parseFloatingLiteral( in, end, ¤t ); - } else if( isStringLiteral( *in ) ) { - in = parseStringLiteral( in, end, ¤t ); - } else if( isHexLiteral( in, end ) ) { - in = parseHexaLiteral( in, end, ¤t ); - } else { // reference data - std::vector names; - in = parseReference( in, end, names ); - if( !names.empty() ) { - Reference *ref = new Reference( names.size(), &names[ 0 ] ); - *refs = ref; - numRefs = names.size(); - } - } - - if( ddl_nullptr != current ) { - if( ddl_nullptr == *data ) { - *data = current; - prev = current; - } else { - prev->setNext( current ); - prev = current; - } - numValues++; - } - - in = getNextSeparator( in, end ); - if( ',' != *in && '}' != *in && !isSpace( *in ) ) { - break; - } - } - in++; - } - - return in; -} - -static DataArrayList *createDataArrayList( Value *currentValue, size_t numValues ) { - DataArrayList *dataList = new DataArrayList; - dataList->m_dataList = currentValue; - dataList->m_numItems = numValues; - - return dataList; - -} -char *OpenDDLParser::parseDataArrayList( char *in, char *end, DataArrayList **dataList ) { - *dataList = ddl_nullptr; - if( ddl_nullptr == in || in == end ) { - return in; - } - - in = lookForNextToken( in, end ); - if( *in == Grammar::OpenBracketToken[ 0 ] ) { - in++; - Value *currentValue( ddl_nullptr ); - Reference *refs( ddl_nullptr ); - DataArrayList *prev( ddl_nullptr ), *currentDataList( ddl_nullptr ); - do { - size_t numRefs( 0 ), numValues( 0 ); - currentValue = ddl_nullptr; - in = parseDataList( in, end, ¤tValue, numValues, &refs, numRefs ); - if( ddl_nullptr != currentValue ) { - if( ddl_nullptr == prev ) { - *dataList = createDataArrayList( currentValue, numValues ); - prev = *dataList; - } else { - currentDataList = createDataArrayList( currentValue, numValues ); - if( ddl_nullptr != prev ) { - prev->m_next = currentDataList; - prev = currentDataList; - } - } - } - } while( Grammar::CommaSeparator[ 0 ] == *in && in != end ); - in = lookForNextToken( in, end ); - in++; - } - - return in; -} - -const char *OpenDDLParser::getVersion() { - return Version; -} - -END_ODDLPARSER_NS diff --git a/contrib/openddlparser/include/openddlparser/Value.cpp b/contrib/openddlparser/include/openddlparser/Value.cpp deleted file mode 100644 index 78ae00c92..000000000 --- a/contrib/openddlparser/include/openddlparser/Value.cpp +++ /dev/null @@ -1,336 +0,0 @@ -/*----------------------------------------------------------------------------------------------- -The MIT License (MIT) - -Copyright (c) 2014-2015 Kim Kulling - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ------------------------------------------------------------------------------------------------*/ -#include - -#include -#include - -BEGIN_ODDLPARSER_NS - -Value::Iterator::Iterator() -: m_start( ddl_nullptr ) -, m_current( ddl_nullptr ) { - // empty -} - -Value::Iterator::Iterator( Value *start ) -: m_start( start ) -, m_current( start ) { - // empty -} - -Value::Iterator::~Iterator() { - // empty -} - -bool Value::Iterator::hasNext() const { - if( ddl_nullptr == m_current ) { - return false; - } - return ( ddl_nullptr != m_current->getNext() ); -} - -Value *Value::Iterator::getNext() { - if( !hasNext() ) { - return ddl_nullptr; - } - - Value *v( m_current->getNext() ); - m_current = v; - - return v; -} - -Value::Value( ValueType type ) -: m_type( type ) -, m_size( 0 ) -, m_data( ddl_nullptr ) -, m_next( ddl_nullptr ) { - // empty -} - -Value::~Value() { - // empty -} - -void Value::setBool( bool value ) { - assert( ddl_bool == m_type ); - ::memcpy( m_data, &value, m_size ); -} - -bool Value::getBool() { - assert( ddl_bool == m_type ); - return ( *m_data ) ? true : false; -} - -void Value::setInt8( int8 value ) { - assert( ddl_int8 == m_type ); - ::memcpy( m_data, &value, m_size ); -} - -int8 Value::getInt8() { - assert( ddl_int8 == m_type ); - return ( int8 ) ( *m_data ); -} - -void Value::setInt16( int16 value ) { - assert( ddl_int16 == m_type ); - ::memcpy( m_data, &value, m_size ); -} - -int16 Value::getInt16() { - assert( ddl_int16 == m_type ); - return ( int16 ) ( *m_data ); -} - -void Value::setInt32( int32 value ) { - assert( ddl_int32 == m_type ); - ::memcpy( m_data, &value, m_size ); -} - -int32 Value::getInt32() { - assert( ddl_int32 == m_type ); - return ( int32 ) ( *m_data ); -} - -void Value::setInt64( int64 value ) { - assert( ddl_int32 == m_type ); - ::memcpy( m_data, &value, m_size ); -} - -int64 Value::getInt64() { - return ( int64 ) ( *m_data ); -} - -void Value::setUnsignedInt8( uint8 value ) { - assert( ddl_unsigned_int8 == m_type ); - ::memcpy( m_data, &value, m_size ); -} - -uint8 Value::getUnsignedInt8() const { - assert( ddl_unsigned_int8 == m_type ); - return ( uint8 ) ( *m_data ); -} - -void Value::setUnsignedInt16( uint16 value ) { - assert( ddl_unsigned_int16 == m_type ); - ::memcpy( m_data, &value, m_size ); -} - -uint16 Value::getUnsignedInt16() const { - assert( ddl_unsigned_int16 == m_type ); - return ( uint8 ) ( *m_data ); -} - -void Value::setUnsignedInt32( uint32 value ) { - assert( ddl_unsigned_int32 == m_type ); - ::memcpy( m_data, &value, m_size ); -} - -uint32 Value::getUnsignedInt32() const { - assert( ddl_unsigned_int32 == m_type ); - return ( uint8 ) ( *m_data ); -} - -void Value::setUnsignedInt64( uint64 value ) { - assert( ddl_unsigned_int64 == m_type ); - ::memcpy( m_data, &value, m_size ); -} - -uint64 Value::getUnsignedInt64() const { - assert( ddl_unsigned_int64 == m_type ); - return ( uint64 ) ( *m_data ); -} - -void Value::setFloat( float value ) { - assert( ddl_float == m_type ); - ::memcpy( m_data, &value, m_size ); -} - -float Value::getFloat() const { - if( m_type == ddl_float ) { - float v; - ::memcpy( &v, m_data, m_size ); - return ( float ) v; - } else { - float tmp; - ::memcpy( &tmp, m_data, 4 ); - return ( float ) tmp; - } -} - -void Value::setDouble( double value ) { - assert( ddl_double == m_type ); - ::memcpy( m_data, &value, m_size ); -} - -double Value::getDouble() const { - double v; - ::memcpy( &v, m_data, m_size ); - return v; -} - -void Value::setString( const std::string &str ) { - assert( ddl_string == m_type ); - ::memcpy( m_data, str.c_str(), str.size() ); - m_data[ str.size() ] = '\0'; -} -const char *Value::getString() const { - return (const char*) m_data; -} - -void Value::dump() { - switch( m_type ) { - case ddl_none: - std::cout << "None" << std::endl; - break; - case ddl_bool: - std::cout << getBool() << std::endl; - break; - case ddl_int8: - std::cout << getInt8() << std::endl; - break; - case ddl_int16: - std::cout << getInt16() << std::endl; - break; - case ddl_int32: - std::cout << getInt32() << std::endl; - break; - case ddl_int64: - std::cout << getInt64() << std::endl; - break; - case ddl_unsigned_int8: - std::cout << "Not supported" << std::endl; - break; - case ddl_unsigned_int16: - std::cout << "Not supported" << std::endl; - break; - case ddl_unsigned_int32: - std::cout << "Not supported" << std::endl; - break; - case ddl_unsigned_int64: - std::cout << "Not supported" << std::endl; - break; - case ddl_half: - std::cout << "Not supported" << std::endl; - break; - case ddl_float: - std::cout << getFloat() << std::endl; - break; - case ddl_double: - std::cout << getDouble() << std::endl; - break; - case ddl_string: - std::cout << "Not supported" << std::endl; - break; - case ddl_ref: - std::cout << "Not supported" << std::endl; - break; - default: - break; - } -} - -void Value::setNext( Value *next ) { - m_next = next; -} - -Value *Value::getNext() const { - return m_next; -} - -Value *ValueAllocator::allocPrimData( Value::ValueType type, size_t len ) { - if( type == Value::ddl_none || Value::ddl_types_max == type ) { - return ddl_nullptr; - } - - Value *data = new Value( type ); - data->m_type = type; - switch( type ) { - case Value::ddl_bool: - data->m_size = sizeof( bool ); - break; - case Value::ddl_int8: - data->m_size = sizeof( char ); - break; - case Value::ddl_int16: - data->m_size = sizeof( short ); - break; - case Value::ddl_int32: - data->m_size = sizeof( int ); - break; - case Value::ddl_int64: - data->m_size = sizeof( int64 ); - break; - case Value::ddl_unsigned_int8: - data->m_size = sizeof( unsigned char ); - break; - case Value::ddl_unsigned_int32: - data->m_size = sizeof( unsigned int ); - break; - case Value::ddl_unsigned_int64: - data->m_size = sizeof( uint64 ); - break; - case Value::ddl_half: - data->m_size = sizeof( short ); - break; - case Value::ddl_float: - data->m_size = sizeof( float ); - break; - case Value::ddl_double: - data->m_size = sizeof( double ); - break; - case Value::ddl_string: - data->m_size = sizeof( char ); - break; - case Value::ddl_ref: - data->m_size = sizeof( char ); - break; - case Value::ddl_none: - case Value::ddl_types_max: - default: - break; - } - - if( data->m_size ) { - size_t len1( len ); - if( Value::ddl_string == type ) { - len1++; - } - data->m_size *= len1; - data->m_data = new unsigned char[ data->m_size ]; - } - - return data; -} - -void ValueAllocator::releasePrimData( Value **data ) { - if( !data ) { - return; - } - - delete *data; - *data = ddl_nullptr; -} - -END_ODDLPARSER_NS diff --git a/workspaces/xcode6/Assimp.xcodeproj/project.pbxproj b/workspaces/xcode6/Assimp.xcodeproj/project.pbxproj index c7192dc45..14c4598bd 100644 --- a/workspaces/xcode6/Assimp.xcodeproj/project.pbxproj +++ b/workspaces/xcode6/Assimp.xcodeproj/project.pbxproj @@ -161,11 +161,11 @@ 7F7924C21AB43E20005A8E5D /* sweep_context.cc in Sources */ = {isa = PBXBuildFile; fileRef = 5E10483FBE6D4F4594B460E0 /* sweep_context.cc */; }; 7F7924C31AB43E20005A8E5D /* ioapi.c in Sources */ = {isa = PBXBuildFile; fileRef = AF75E6049338489BB256D295 /* ioapi.c */; }; 7F7924C41AB43E20005A8E5D /* unzip.c in Sources */ = {isa = PBXBuildFile; fileRef = 973D4231A4AA4925B019FEEE /* unzip.c */; }; + 7F7A93A81B65D0110094C4DA /* DDLNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7F7A93A51B65D0110094C4DA /* DDLNode.cpp */; }; + 7F7A93A91B65D0110094C4DA /* OpenDDLParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7F7A93A61B65D0110094C4DA /* OpenDDLParser.cpp */; }; + 7F7A93AA1B65D0110094C4DA /* Value.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7F7A93A71B65D0110094C4DA /* Value.cpp */; }; 7FBE9FEA1B65AC1200D2115E /* OpenGEXExporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7FBE9FE51B65AC1200D2115E /* OpenGEXExporter.cpp */; }; 7FBE9FEB1B65AC1200D2115E /* OpenGEXImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7FBE9FE71B65AC1200D2115E /* OpenGEXImporter.cpp */; }; - 7FBEA00E1B65AF9200D2115E /* DDLNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7FBEA0061B65AF9200D2115E /* DDLNode.cpp */; }; - 7FBEA00F1B65AF9200D2115E /* OpenDDLParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7FBEA0091B65AF9200D2115E /* OpenDDLParser.cpp */; }; - 7FBEA0101B65AF9200D2115E /* Value.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7FBEA00C1B65AF9200D2115E /* Value.cpp */; }; 7FBEA0121B65B11800D2115E /* Version.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7FBEA0111B65B11800D2115E /* Version.cpp */; }; /* End PBXBuildFile section */ @@ -368,18 +368,18 @@ 7F29EF981AB26C4900E9D380 /* libz.1.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.1.dylib; path = /usr/lib/libz.1.dylib; sourceTree = ""; }; 7F392D921AB2C7BB00D952EB /* libc++.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libc++.dylib"; path = "/usr/lib/libc++.dylib"; sourceTree = ""; }; 7F7922801AB43AC3005A8E5D /* libassimp.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libassimp.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 7F7A93A51B65D0110094C4DA /* DDLNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DDLNode.cpp; path = contrib/openddlparser/code/DDLNode.cpp; sourceTree = ""; }; + 7F7A93A61B65D0110094C4DA /* OpenDDLParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OpenDDLParser.cpp; path = contrib/openddlparser/code/OpenDDLParser.cpp; sourceTree = ""; }; + 7F7A93A71B65D0110094C4DA /* Value.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Value.cpp; path = contrib/openddlparser/code/Value.cpp; sourceTree = ""; }; 7FBE9FE51B65AC1200D2115E /* OpenGEXExporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OpenGEXExporter.cpp; path = code/OpenGEXExporter.cpp; sourceTree = ""; }; 7FBE9FE61B65AC1200D2115E /* OpenGEXExporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OpenGEXExporter.h; path = code/OpenGEXExporter.h; sourceTree = ""; }; 7FBE9FE71B65AC1200D2115E /* OpenGEXImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OpenGEXImporter.cpp; path = code/OpenGEXImporter.cpp; sourceTree = ""; }; 7FBE9FE81B65AC1200D2115E /* OpenGEXImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OpenGEXImporter.h; path = code/OpenGEXImporter.h; sourceTree = ""; }; 7FBE9FE91B65AC1200D2115E /* OpenGEXStructs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OpenGEXStructs.h; path = code/OpenGEXStructs.h; sourceTree = ""; }; - 7FBEA0061B65AF9200D2115E /* DDLNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DDLNode.cpp; path = contrib/openddlparser/include/openddlparser/DDLNode.cpp; sourceTree = ""; }; 7FBEA0071B65AF9200D2115E /* DDLNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DDLNode.h; path = contrib/openddlparser/include/openddlparser/DDLNode.h; sourceTree = ""; }; 7FBEA0081B65AF9200D2115E /* OpenDDLCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OpenDDLCommon.h; path = contrib/openddlparser/include/openddlparser/OpenDDLCommon.h; sourceTree = ""; }; - 7FBEA0091B65AF9200D2115E /* OpenDDLParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OpenDDLParser.cpp; path = contrib/openddlparser/include/openddlparser/OpenDDLParser.cpp; sourceTree = ""; }; 7FBEA00A1B65AF9200D2115E /* OpenDDLParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OpenDDLParser.h; path = contrib/openddlparser/include/openddlparser/OpenDDLParser.h; sourceTree = ""; }; 7FBEA00B1B65AF9200D2115E /* OpenDDLParserUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OpenDDLParserUtils.h; path = contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h; sourceTree = ""; }; - 7FBEA00C1B65AF9200D2115E /* Value.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Value.cpp; path = contrib/openddlparser/include/openddlparser/Value.cpp; sourceTree = ""; }; 7FBEA00D1B65AF9200D2115E /* Value.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Value.h; path = contrib/openddlparser/include/openddlparser/Value.h; sourceTree = ""; }; 7FBEA0111B65B11800D2115E /* Version.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Version.cpp; path = code/Version.cpp; sourceTree = ""; }; 7FF72CB6E99E40E19AE0E64C /* MaterialSystem.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = MaterialSystem.cpp; path = code/MaterialSystem.cpp; sourceTree = SOURCE_ROOT; }; @@ -1079,14 +1079,14 @@ 7FBEA0051B65AF8900D2115E /* openddlparser */ = { isa = PBXGroup; children = ( - 7FBEA0061B65AF9200D2115E /* DDLNode.cpp */, - 7FBEA0071B65AF9200D2115E /* DDLNode.h */, 7FBEA0081B65AF9200D2115E /* OpenDDLCommon.h */, - 7FBEA0091B65AF9200D2115E /* OpenDDLParser.cpp */, - 7FBEA00A1B65AF9200D2115E /* OpenDDLParser.h */, 7FBEA00B1B65AF9200D2115E /* OpenDDLParserUtils.h */, - 7FBEA00C1B65AF9200D2115E /* Value.cpp */, + 7FBEA0071B65AF9200D2115E /* DDLNode.h */, + 7F7A93A51B65D0110094C4DA /* DDLNode.cpp */, + 7FBEA00A1B65AF9200D2115E /* OpenDDLParser.h */, + 7F7A93A61B65D0110094C4DA /* OpenDDLParser.cpp */, 7FBEA00D1B65AF9200D2115E /* Value.h */, + 7F7A93A71B65D0110094C4DA /* Value.cpp */, ); name = openddlparser; sourceTree = ""; @@ -1592,11 +1592,11 @@ 7F79244A1AB43E20005A8E5D /* DeboneProcess.cpp in Sources */, 7F79244B1AB43E20005A8E5D /* DefaultIOStream.cpp in Sources */, 7F79244C1AB43E20005A8E5D /* DefaultIOSystem.cpp in Sources */, + 7F7A93A81B65D0110094C4DA /* DDLNode.cpp in Sources */, 7F79244D1AB43E20005A8E5D /* DefaultLogger.cpp in Sources */, 7F79244E1AB43E20005A8E5D /* Exporter.cpp in Sources */, 7F79244F1AB43E20005A8E5D /* FBXAnimation.cpp in Sources */, 7F7924501AB43E20005A8E5D /* FBXBinaryTokenizer.cpp in Sources */, - 7FBEA0101B65AF9200D2115E /* Value.cpp in Sources */, 7F7924511AB43E20005A8E5D /* FBXConverter.cpp in Sources */, 7F7924521AB43E20005A8E5D /* FBXDeformer.cpp in Sources */, 7F7924531AB43E20005A8E5D /* FBXDocument.cpp in Sources */, @@ -1610,6 +1610,7 @@ 7F79245B1AB43E20005A8E5D /* FBXProperties.cpp in Sources */, 7F79245C1AB43E20005A8E5D /* FBXTokenizer.cpp in Sources */, 7F79245D1AB43E20005A8E5D /* FBXUtil.cpp in Sources */, + 7F7A93A91B65D0110094C4DA /* OpenDDLParser.cpp in Sources */, 7F79245E1AB43E20005A8E5D /* FindDegenerates.cpp in Sources */, 7F79245F1AB43E20005A8E5D /* FindInstancesProcess.cpp in Sources */, 7F7924601AB43E20005A8E5D /* FindInvalidDataProcess.cpp in Sources */, @@ -1632,7 +1633,6 @@ 7F7924701AB43E20005A8E5D /* IRRShared.cpp in Sources */, 7F7924711AB43E20005A8E5D /* Importer.cpp in Sources */, 7F7924721AB43E20005A8E5D /* ImporterRegistry.cpp in Sources */, - 7FBEA00E1B65AF9200D2115E /* DDLNode.cpp in Sources */, 7F7924731AB43E20005A8E5D /* ImproveCacheLocality.cpp in Sources */, 7F7924741AB43E20005A8E5D /* JoinVerticesProcess.cpp in Sources */, 7F7924751AB43E20005A8E5D /* LWOAnimation.cpp in Sources */, @@ -1641,7 +1641,6 @@ 7F7924781AB43E20005A8E5D /* LWOMaterial.cpp in Sources */, 7F7924791AB43E20005A8E5D /* LWSLoader.cpp in Sources */, 7F79247A1AB43E20005A8E5D /* LimitBoneWeightsProcess.cpp in Sources */, - 7FBEA00F1B65AF9200D2115E /* OpenDDLParser.cpp in Sources */, 7F79247B1AB43E20005A8E5D /* MD2Loader.cpp in Sources */, 7F79247C1AB43E20005A8E5D /* MD3Loader.cpp in Sources */, 7F79247D1AB43E20005A8E5D /* MD5Loader.cpp in Sources */, @@ -1673,6 +1672,7 @@ 7F7924961AB43E20005A8E5D /* PostStepRegistry.cpp in Sources */, 7F7924971AB43E20005A8E5D /* PretransformVertices.cpp in Sources */, 7F7924981AB43E20005A8E5D /* ProcessHelper.cpp in Sources */, + 7F7A93AA1B65D0110094C4DA /* Value.cpp in Sources */, 7F7924991AB43E20005A8E5D /* Q3BSPFileImporter.cpp in Sources */, 7F79249A1AB43E20005A8E5D /* Q3BSPFileParser.cpp in Sources */, 7F79249B1AB43E20005A8E5D /* Q3BSPZipArchive.cpp in Sources */, From 227a08d2b7693b1b64ed8cf52fae1b71913d9f2e Mon Sep 17 00:00:00 2001 From: Wil Shipley Date: Sun, 26 Jul 2015 19:50:32 -0700 Subject: [PATCH 18/51] - These were Xcode's git control files and will vary from person to person. --- .../xcshareddata/Assimp.xccheckout | 53 ------------------- .../xcshareddata/Assimp.xcscmblueprint | 30 ----------- 2 files changed, 83 deletions(-) delete mode 100644 workspaces/xcode6/Assimp.xcodeproj/project.xcworkspace/xcshareddata/Assimp.xccheckout delete mode 100644 workspaces/xcode6/Assimp.xcodeproj/project.xcworkspace/xcshareddata/Assimp.xcscmblueprint diff --git a/workspaces/xcode6/Assimp.xcodeproj/project.xcworkspace/xcshareddata/Assimp.xccheckout b/workspaces/xcode6/Assimp.xcodeproj/project.xcworkspace/xcshareddata/Assimp.xccheckout deleted file mode 100644 index 475229dbd..000000000 --- a/workspaces/xcode6/Assimp.xcodeproj/project.xcworkspace/xcshareddata/Assimp.xccheckout +++ /dev/null @@ -1,53 +0,0 @@ - - - - - IDESourceControlProjectFavoriteDictionaryKey - - IDESourceControlProjectIdentifier - D62E7BFA-CF67-4098-A3F5-28B460E459FD - IDESourceControlProjectName - Assimp - IDESourceControlProjectOriginsDictionary - - AE3F0F79FA18959EE39DE06BF81D40ADA159F259 - https://github.com/delicious-monster/assimp.git - BAB24031A51D728DF843C2AED36E4506ECB1FFC2 - savory:UberDwelling.git - - IDESourceControlProjectPath - workspaces/xcode6/Assimp.xcodeproj - IDESourceControlProjectRelativeInstallPathDictionary - - AE3F0F79FA18959EE39DE06BF81D40ADA159F259 - ../../../.. - BAB24031A51D728DF843C2AED36E4506ECB1FFC2 - ../../../../.. - - IDESourceControlProjectURL - https://github.com/delicious-monster/assimp.git - IDESourceControlProjectVersion - 111 - IDESourceControlProjectWCCIdentifier - AE3F0F79FA18959EE39DE06BF81D40ADA159F259 - IDESourceControlProjectWCConfigurations - - - IDESourceControlRepositoryExtensionIdentifierKey - public.vcs.git - IDESourceControlWCCIdentifierKey - BAB24031A51D728DF843C2AED36E4506ECB1FFC2 - IDESourceControlWCCName - - - - IDESourceControlRepositoryExtensionIdentifierKey - public.vcs.git - IDESourceControlWCCIdentifierKey - AE3F0F79FA18959EE39DE06BF81D40ADA159F259 - IDESourceControlWCCName - assimp - - - - diff --git a/workspaces/xcode6/Assimp.xcodeproj/project.xcworkspace/xcshareddata/Assimp.xcscmblueprint b/workspaces/xcode6/Assimp.xcodeproj/project.xcworkspace/xcshareddata/Assimp.xcscmblueprint deleted file mode 100644 index 1db9edd4b..000000000 --- a/workspaces/xcode6/Assimp.xcodeproj/project.xcworkspace/xcshareddata/Assimp.xcscmblueprint +++ /dev/null @@ -1,30 +0,0 @@ -{ - "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "AE3F0F79FA18959EE39DE06BF81D40ADA159F259", - "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : { - - }, - "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : { - "AE3F0F79FA18959EE39DE06BF81D40ADA159F259" : 0, - "BAB24031A51D728DF843C2AED36E4506ECB1FFC2" : 0 - }, - "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "D62E7BFA-CF67-4098-A3F5-28B460E459FD", - "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : { - "AE3F0F79FA18959EE39DE06BF81D40ADA159F259" : "assimp", - "BAB24031A51D728DF843C2AED36E4506ECB1FFC2" : "" - }, - "DVTSourceControlWorkspaceBlueprintNameKey" : "Assimp", - "DVTSourceControlWorkspaceBlueprintVersion" : 203, - "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "workspaces\/xcode6\/Assimp.xcodeproj", - "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [ - { - "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/github.com\/delicious-monster\/assimp.git", - "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", - "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "AE3F0F79FA18959EE39DE06BF81D40ADA159F259" - }, - { - "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "savory:UberDwelling.git", - "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", - "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "BAB24031A51D728DF843C2AED36E4506ECB1FFC2" - } - ] -} \ No newline at end of file From 7a7a4963205d1242847a9cc9c8b72542468392f0 Mon Sep 17 00:00:00 2001 From: Wil Shipley Date: Mon, 27 Jul 2015 00:54:23 -0700 Subject: [PATCH 19/51] - Add include of stdarg, because apparently that's needed to build of Github server with Travis. --- code/ColladaParser.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/code/ColladaParser.cpp b/code/ColladaParser.cpp index 33225e6a1..ddfab79f1 100644 --- a/code/ColladaParser.cpp +++ b/code/ColladaParser.cpp @@ -47,6 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef ASSIMP_BUILD_NO_COLLADA_IMPORTER #include +#include #include "ColladaParser.h" #include "fast_atof.h" #include "ParsingUtils.h" From bb8d9362461813ccba16291cfba8ac225e470cd9 Mon Sep 17 00:00:00 2001 From: Ilya Smelkov Date: Sun, 2 Aug 2015 19:45:39 +0300 Subject: [PATCH 20/51] Fix volume calculation --- code/FixNormalsStep.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/FixNormalsStep.cpp b/code/FixNormalsStep.cpp index 426e7fbeb..5fe139e4b 100644 --- a/code/FixNormalsStep.cpp +++ b/code/FixNormalsStep.cpp @@ -152,8 +152,8 @@ bool FixInfacingNormalsProcess::ProcessMesh( aiMesh* pcMesh, unsigned int index) if (fDelta1_z < 0.05f * sqrtf( fDelta1_y * fDelta1_x ))return false; // now compare the volumes of the bounding boxes - if (std::fabs(fDelta0_x * fDelta1_yz) < - std::fabs(fDelta1_x * fDelta1_y * fDelta1_z)) + if (std::fabs(fDelta0_x * fDelta0_y * fDelta0_z) < + std::fabs(fDelta1_x * fDelta1_yz)) { if (!DefaultLogger::isNullLogger()) { From fb9e4d126673adf722dc00924dd1dd51487fadc3 Mon Sep 17 00:00:00 2001 From: Andreas Henne Date: Thu, 6 Aug 2015 13:30:49 +0200 Subject: [PATCH 21/51] Ply export now uses uchar as type for the number of vertices per polygon and int as vertex index type. --- code/PlyExporter.cpp | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/code/PlyExporter.cpp b/code/PlyExporter.cpp index 9268794f0..f8ff34fc2 100644 --- a/code/PlyExporter.cpp +++ b/code/PlyExporter.cpp @@ -189,7 +189,12 @@ PlyExporter::PlyExporter(const char* _filename, const aiScene* pScene, bool bina } mOutput << "element face " << faces << endl; - mOutput << "property list uint uint vertex_index" << endl; + + // uchar seems to be the most common type for the number of indices per polygon and int seems to be most common for the vertex indices. + // For instance, MeshLab fails to load meshes in which both types are uint. Houdini seems to have problems as well. + // Obviously, using unchar will not work for meshes with polygons with more than 255 indices, but how realistic is this case? + mOutput << "property list uchar int vertex_index" << endl; + mOutput << "end_header" << endl; for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) { @@ -342,16 +347,24 @@ void PlyExporter::WriteMeshIndices(const aiMesh* m, unsigned int offset) } } -void PlyExporter::WriteMeshIndicesBinary(const aiMesh* m, unsigned int offset) +// Generic method in case we want to use different data types for the indices or make this configurable. +template +void WriteMeshIndicesBinary_Generic(const aiMesh* m, unsigned int offset, std::ostringstream& output) { for (unsigned int i = 0; i < m->mNumFaces; ++i) { const aiFace& f = m->mFaces[i]; - mOutput.write(reinterpret_cast(&f.mNumIndices), 4); + NumIndicesType numIndices = static_cast(f.mNumIndices); + output.write(reinterpret_cast(&numIndices), sizeof(NumIndicesType)); for (unsigned int c = 0; c < f.mNumIndices; ++c) { - unsigned int index = f.mIndices[c] + offset; - mOutput.write(reinterpret_cast(&index), 4); + IndexType index = f.mIndices[c] + offset; + output.write(reinterpret_cast(&index), sizeof(IndexType)); } } } +void PlyExporter::WriteMeshIndicesBinary(const aiMesh* m, unsigned int offset) +{ + WriteMeshIndicesBinary_Generic(m, offset, mOutput); +} + #endif From 5030fe8c7e7479f83b58e92f83b5604986b00baf Mon Sep 17 00:00:00 2001 From: Andreas Henne Date: Thu, 6 Aug 2015 13:37:16 +0200 Subject: [PATCH 22/51] Formatting changes. --- code/STLLoader.cpp | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/code/STLLoader.cpp b/code/STLLoader.cpp index 79ed37c66..df15bdbfa 100644 --- a/code/STLLoader.cpp +++ b/code/STLLoader.cpp @@ -3,12 +3,12 @@ Open Asset Import Library (assimp) --------------------------------------------------------------------------- -Copyright (c) 2006-2012, assimp team +Copyright (c) 2006-2015, assimp team All rights reserved. -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above @@ -25,16 +25,16 @@ conditions are met: derived from this software without specific prior written permission of the assimp team. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --------------------------------------------------------------------------- */ @@ -53,6 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "../include/assimp/scene.h" #include "../include/assimp/DefaultLogger.hpp" + using namespace Assimp; namespace { @@ -111,19 +112,19 @@ STLImporter::STLImporter() {} // ------------------------------------------------------------------------------------------------ -// Destructor, private as well +// Destructor, private as well STLImporter::~STLImporter() {} // ------------------------------------------------------------------------------------------------ -// Returns whether the class can handle the format of the given file. +// Returns whether the class can handle the format of the given file. bool STLImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const { const std::string extension = GetExtension(pFile); if (extension == "stl") return true; - else if (!extension.length() || checkSig) { + else if (!extension.length() || checkSig) { if (!pIOHandler) return true; const char* tokens[] = {"STL","solid"}; @@ -152,14 +153,14 @@ void addFacesToMesh(aiMesh* pMesh) } // ------------------------------------------------------------------------------------------------ -// Imports the given file into the given scene structure. -void STLImporter::InternReadFile( const std::string& pFile, +// Imports the given file into the given scene structure. +void STLImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) { boost::scoped_ptr file( pIOHandler->Open( pFile, "rb")); // Check whether we can read from the file - if( file.get() == NULL) { + if( file.get() == NULL) { throw DeadlyImportError( "Failed to open STL file " + pFile + "."); } @@ -388,7 +389,7 @@ bool STLImporter::LoadBinaryFile() // search for an occurence of "COLOR=" in the header const unsigned char* sz2 = (const unsigned char*)mBuffer; const unsigned char* const szEnd = sz2+80; - while (sz2 < szEnd) { + while (sz2 < szEnd) { if ('C' == *sz2++ && 'O' == *sz2++ && 'L' == *sz2++ && 'O' == *sz2++ && 'R' == *sz2++ && '=' == *sz2++) { @@ -425,7 +426,7 @@ bool STLImporter::LoadBinaryFile() vp = pMesh->mVertices = new aiVector3D[pMesh->mNumVertices]; vn = pMesh->mNormals = new aiVector3D[pMesh->mNumVertices]; - for (unsigned int i = 0; i < pMesh->mNumFaces;++i) { + for (unsigned int i = 0; i < pMesh->mNumFaces;++i) { // NOTE: Blender sometimes writes empty normals ... this is not // our fault ... the RemoveInvalidData helper step should fix that From 128923a262e6e39a9168a4eb31c56b9cc01686ad Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Thu, 6 Aug 2015 16:16:34 +0300 Subject: [PATCH 23/51] Fix out-of-bounds write on malformed input --- code/LWOLoader.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/LWOLoader.cpp b/code/LWOLoader.cpp index 5ec073507..8de88055b 100644 --- a/code/LWOLoader.cpp +++ b/code/LWOLoader.cpp @@ -954,6 +954,9 @@ inline void LWOImporter::DoRecursiveVMAPAssignment(VMapEntry* base, unsigned int LWO::ReferrerList& refList = mCurLayer->mPointReferrers; unsigned int i; + if (idx >= base->abAssigned.size()) { + throw DeadlyImportError("Bad index"); + } base->abAssigned[idx] = true; for (i = 0; i < numRead;++i) { base->rawData[idx*base->dims+i]= data[i]; From 154760ab52efedc85bc97fa85c0bbf04c07c2b75 Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Fri, 7 Aug 2015 14:17:27 +0300 Subject: [PATCH 24/51] Abort early when hitting unexpected EOF in AC3D loader Without this the code will try to loop through the specified number of surfaces which could be very large even though none will succeed. --- code/ACLoader.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/code/ACLoader.cpp b/code/ACLoader.cpp index 5b7b6a61d..dac85b8db 100644 --- a/code/ACLoader.cpp +++ b/code/ACLoader.cpp @@ -349,8 +349,7 @@ void AC3DImporter::LoadObjectSection(std::vector& objects) { if(!GetNextLine()) { - DefaultLogger::get()->error("AC3D: Unexpected EOF: surface is incomplete"); - break; + throw DeadlyImportError("AC3D: Unexpected EOF: surface is incomplete"); } if (TokenMatch(buffer,"mat",3)) { From 8836fd6b34e282c1275b7847f12bde4e70dd90c7 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Fri, 7 Aug 2015 21:18:20 +0200 Subject: [PATCH 25/51] PLY-Loader: fix https://github.com/assimp/assimp/issues/160. --- code/PlyLoader.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/code/PlyLoader.cpp b/code/PlyLoader.cpp index 65c9ba284..f86ddcead 100644 --- a/code/PlyLoader.cpp +++ b/code/PlyLoader.cpp @@ -310,6 +310,10 @@ void PLYImporter::ConvertMeshes(std::vector* avFaces, iNum += (unsigned int)(*avFaces)[aiSplit[p][i]].mIndices.size(); } p_pcOut->mNumVertices = iNum; + if( 0 == iNum ) { // nothing to do + delete[] aiSplit; // cleanup + return; + } p_pcOut->mVertices = new aiVector3D[iNum]; if (!avColors->empty()) @@ -335,20 +339,25 @@ void PLYImporter::ConvertMeshes(std::vector* avFaces, for (unsigned int q = 0; q < p_pcOut->mFaces[iNum].mNumIndices;++q) { p_pcOut->mFaces[iNum].mIndices[q] = iVertex; - p_pcOut->mVertices[iVertex] = (*avPositions)[(*avFaces)[*i].mIndices[q]]; + const size_t idx = ( *avFaces )[ *i ].mIndices[ q ]; + if( idx >= ( *avPositions ).size() ) { + // out of border + continue; + } + p_pcOut->mVertices[ iVertex ] = ( *avPositions )[ idx ]; if (!avColors->empty()) - p_pcOut->mColors[0][iVertex] = (*avColors)[(*avFaces)[*i].mIndices[q]]; + p_pcOut->mColors[ 0 ][ iVertex ] = ( *avColors )[ idx ]; if (!avTexCoords->empty()) { - const aiVector2D& vec = (*avTexCoords)[(*avFaces)[*i].mIndices[q]]; + const aiVector2D& vec = ( *avTexCoords )[ idx ]; p_pcOut->mTextureCoords[0][iVertex].x = vec.x; p_pcOut->mTextureCoords[0][iVertex].y = vec.y; } if (!avNormals->empty()) - p_pcOut->mNormals[iVertex] = (*avNormals)[(*avFaces)[*i].mIndices[q]]; + p_pcOut->mNormals[ iVertex ] = ( *avNormals )[ idx ]; iVertex++; } From 88746af2e6d56568f40d3009f6b20cd235f5943a Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Fri, 7 Aug 2015 21:22:09 +0200 Subject: [PATCH 26/51] Blender-Loader: fix issue https://github.com/assimp/assimp/issues/131. --- code/BlenderScene.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/BlenderScene.h b/code/BlenderScene.h index ca750bb84..25c301891 100644 --- a/code/BlenderScene.h +++ b/code/BlenderScene.h @@ -103,7 +103,7 @@ struct Image; // ------------------------------------------------------------------------------- struct ID : ElemBase { - char name[24] WARN; + char name[1024] WARN; short flag; }; From e794aaf017f7b03a788774987d0024457f36f744 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sat, 8 Aug 2015 10:55:10 +0200 Subject: [PATCH 27/51] STL-Loader: fix https://github.com/assimp/assimp/issues/103. --- code/STLLoader.cpp | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/code/STLLoader.cpp b/code/STLLoader.cpp index fb05be760..01a01c79e 100644 --- a/code/STLLoader.cpp +++ b/code/STLLoader.cpp @@ -75,8 +75,9 @@ static const aiImporterDesc desc = { // 2) 4 byte face count // 3) 50 bytes per face bool IsBinarySTL(const char* buffer, unsigned int fileSize) { - if (fileSize < 84) + if( fileSize < 84 ) { return false; + } const uint32_t faceCount = *reinterpret_cast(buffer + 80); const uint32_t expectedBinaryFileSize = faceCount * 50 + 84; @@ -99,7 +100,20 @@ bool IsAsciiSTL(const char* buffer, unsigned int fileSize) { if (buffer + 5 >= bufferEnd) return false; - return strncmp(buffer, "solid", 5) == 0; + bool isASCII( strncmp( buffer, "solid", 5 ) == 0 ); + if( isASCII ) { + // A lot of importers are write solit even if the file is binary. So we have to check for ascii characters. + if( fileSize >= 500 ) { + isASCII = true; + for( unsigned int i = 0; i < 500; i++ ) { + if( buffer[ i ] > 127 ) { + isASCII = false; + break; + } + } + } + } + return isASCII; } } // namespace @@ -122,20 +136,21 @@ bool STLImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool { const std::string extension = GetExtension(pFile); - if (extension == "stl") + if( extension == "stl" ) { return true; - else if (!extension.length() || checkSig) { - if (!pIOHandler) + } else if (!extension.length() || checkSig) { + if( !pIOHandler ) { return true; + } const char* tokens[] = {"STL","solid"}; return SearchFileHeaderForToken(pIOHandler,pFile,tokens,2); } + return false; } // ------------------------------------------------------------------------------------------------ -const aiImporterDesc* STLImporter::GetInfo () const -{ +const aiImporterDesc* STLImporter::GetInfo () const { return &desc; } From d8d64a842208b6dd9c0f9beedcc4d4e382ee8e79 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sat, 8 Aug 2015 11:57:15 +0200 Subject: [PATCH 28/51] TLLoader: fix typo in comment. --- code/STLLoader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/STLLoader.cpp b/code/STLLoader.cpp index 01a01c79e..ad445efdb 100644 --- a/code/STLLoader.cpp +++ b/code/STLLoader.cpp @@ -102,7 +102,7 @@ bool IsAsciiSTL(const char* buffer, unsigned int fileSize) { bool isASCII( strncmp( buffer, "solid", 5 ) == 0 ); if( isASCII ) { - // A lot of importers are write solit even if the file is binary. So we have to check for ascii characters. + // A lot of importers are write solid even if the file is binary. So we have to check for ASCII-characters. if( fileSize >= 500 ) { isASCII = true; for( unsigned int i = 0; i < 500; i++ ) { From 85c8d7b89bc8c1e2ad7c7d276d937e1062cf2294 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sat, 8 Aug 2015 17:04:46 +0200 Subject: [PATCH 29/51] PyViewer: Add local path search path for ssimp lib. --- port/PyAssimp/pyassimp/helper.py | 1 + 1 file changed, 1 insertion(+) diff --git a/port/PyAssimp/pyassimp/helper.py b/port/PyAssimp/pyassimp/helper.py index ccfd8d2b5..07d09a568 100644 --- a/port/PyAssimp/pyassimp/helper.py +++ b/port/PyAssimp/pyassimp/helper.py @@ -20,6 +20,7 @@ additional_dirs, ext_whitelist = [],[] # populate search directories and lists of allowed file extensions # depending on the platform we're running on. if os.name=='posix': + additional_dirs.append('./') additional_dirs.append('/usr/lib/') additional_dirs.append('/usr/local/lib/') From e5b61e5553c5f9985bc0d837f8fefca461cc4ccc Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sat, 8 Aug 2015 17:05:29 +0200 Subject: [PATCH 30/51] Python 3d_viewer: init glut manually for windows ( https://github.com/assimp/assimp/issues/622 ). --- port/PyAssimp/scripts/3d_viewer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/port/PyAssimp/scripts/3d_viewer.py b/port/PyAssimp/scripts/3d_viewer.py index cd417bd15..b6c131817 100755 --- a/port/PyAssimp/scripts/3d_viewer.py +++ b/port/PyAssimp/scripts/3d_viewer.py @@ -68,7 +68,7 @@ class PyAssimp3DViewer: pygame.init() pygame.display.set_caption(self.base_name) pygame.display.set_mode((w,h), pygame.OPENGL | pygame.DOUBLEBUF) - + glutInit() self.prepare_shaders() self.cameras = [DefaultCamera(w,h,fov)] From 99e7b221befd7f95da192b336d25addb9cb25c4e Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sat, 8 Aug 2015 17:24:06 +0200 Subject: [PATCH 31/51] CMake build: fix typo in docu.! --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ffbcf5b67..3daa0d6d1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -94,7 +94,7 @@ SET( ASSIMP_INCLUDE_INSTALL_DIR "include" CACHE PATH SET( ASSIMP_BIN_INSTALL_DIR "bin" CACHE PATH "Path the tool executables are installed to." ) -SET(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "Debug Postfitx for lib, samples and tools") +SET(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "Debug Postfix for lib, samples and tools") # Only generate this target if no higher-level project already has IF (NOT TARGET uninstall) From a78e3708d2f75988e50a4f55f80a934954467348 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sat, 8 Aug 2015 17:30:15 +0200 Subject: [PATCH 32/51] CMake build: fix debug postfix, will now be d only for debug builds. --- CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3daa0d6d1..a1a13ef6f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -94,7 +94,11 @@ SET( ASSIMP_INCLUDE_INSTALL_DIR "include" CACHE PATH SET( ASSIMP_BIN_INSTALL_DIR "bin" CACHE PATH "Path the tool executables are installed to." ) -SET(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "Debug Postfix for lib, samples and tools") +IF (CMAKE_BUILD_TYPE STREQUAL "Release") + SET(CMAKE_DEBUG_POSTFIX "" CACHE STRING "Debug Postfix for lib, samples and tools") +ELSE() + SET(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "Debug Postfix for lib, samples and tools") +ENDIF() # Only generate this target if no higher-level project already has IF (NOT TARGET uninstall) From 373f85ffafae82d9f52e36c665119c013d0d8c4d Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sat, 8 Aug 2015 17:31:39 +0200 Subject: [PATCH 33/51] Fix https://github.com/assimp/assimp/issues/620 From 524834c307c4f0949faf943d0eb8869d707700ad Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sat, 8 Aug 2015 18:02:37 +0200 Subject: [PATCH 34/51] Fix line endings. --- code/BoostWorkaround/boost/LICENSE_1_0.txt | 44 +- code/BoostWorkaround/boost/foreach.hpp | 198 +- code/BoostWorkaround/boost/lexical_cast.hpp | 52 +- code/BoostWorkaround/boost/make_shared.hpp | 114 +- .../boost/math/common_factor_rt.hpp | 74 +- code/BoostWorkaround/boost/noncopyable.hpp | 72 +- code/BoostWorkaround/boost/pointer_cast.hpp | 90 +- code/BoostWorkaround/boost/scoped_array.hpp | 158 +- code/BoostWorkaround/boost/scoped_ptr.hpp | 158 +- code/BoostWorkaround/boost/shared_array.hpp | 456 +- code/BoostWorkaround/boost/static_assert.hpp | 40 +- code/BoostWorkaround/boost/tuple/tuple.hpp | 566 +- code/res/resource.h | 28 +- contrib/clipper/License.txt | 58 +- contrib/clipper/clipper.cpp | 6896 ++++++++--------- contrib/clipper/clipper.hpp | 612 +- contrib/irrXML/CXMLReaderImpl.h | 1618 ++-- contrib/irrXML/heapsort.h | 146 +- contrib/irrXML/irrArray.h | 888 +-- contrib/irrXML/irrString.h | 1328 ++-- contrib/irrXML/irrTypes.h | 216 +- contrib/irrXML/irrXML.h | 1080 +-- contrib/irrXML_note.txt | 12 +- contrib/poly2tri/poly2tri/common/utils.h | 210 +- contrib/poly2tri/poly2tri/sweep/cdt.h | 210 +- .../poly2tri/poly2tri/sweep/sweep_context.h | 370 +- contrib/poly2tri_patch.txt | 150 +- contrib/unzip/crypt.h | 264 +- contrib/unzip/ioapi.c | 362 +- contrib/unzip/ioapi.h | 150 +- contrib/unzip/unzip.c | 3208 ++++---- contrib/unzip/unzip.h | 716 +- contrib/zlib/CMakeLists.txt | 398 +- contrib/zlib_note.txt | 20 +- doc/Preamble.txt | 78 +- doc/dox_cmd.h | 1096 +-- include/assimp/Compiler/poppack1.h | 44 +- include/assimp/Compiler/pstdint.h | 1458 ++-- .../port/AndroidJNI/AndroidJNIIOSystem.h | 184 +- .../windows-innosetup/howto-build-setup.txt | 32 +- .../windows-innosetup/readme_installer.txt | 46 +- .../readme_installer_vieweronly.txt | 62 +- packaging/windows-mkzip/bin_readme.txt | 56 +- port/AndroidJNI/AndroidJNIIOSystem.cpp | 350 +- port/AssimpDelphi/Readme.txt | 12 +- samples/DevIL/include/IL/ilut_config.h | 52 +- .../src/model_loading.cpp | 1764 ++--- samples/glut/GL/glut.h | 1432 ++-- samples/glut/README-win32.txt | 1226 +-- test/models-nonbsd/3D/mar_rifle.source.txt | 36 +- test/models-nonbsd/3DS/cart_wheel.source.txt | 36 +- test/models-nonbsd/3DS/jeep1.3ds.readme.txt | 28 +- test/models-nonbsd/3DS/mar_rifle.source.txt | 36 +- test/models-nonbsd/3DS/mp5_sil.source.txt | 36 +- test/models-nonbsd/3DS/pyramob.3ds.readme.txt | 22 +- test/models-nonbsd/ASE/Rifle.source.txt | 48 +- test/models-nonbsd/ASE/Rifle2.source.txt | 46 +- test/models-nonbsd/B3D/dwarf.source.txt | 102 +- test/models-nonbsd/B3D/turtle.source.txt | 20 +- test/models-nonbsd/BLEND/bob.source.txt | 62 +- test/models-nonbsd/DXF/rifle.source.txt | 44 +- test/models-nonbsd/IFC/linklist.txt | 6 +- test/models-nonbsd/IRR/skybox/credits.txt | 22 +- .../LWO2/LWSReferences/QuickDraw.source.txt | 60 +- test/models-nonbsd/LWO/LWO2/rifle.source.txt | 46 +- .../LWS/QuickDraw v2.2.source.txt | 28 +- test/models-nonbsd/MD2/source.txt | 36 +- .../kt_kubalwagon/readme_kubalwagon.txt | 50 +- test/models-nonbsd/MD3/readme_water.txt | 50 +- test/models-nonbsd/MD5/BoarMan.source.txt | 16 +- test/models-nonbsd/MD5/bob.source.txt | 62 +- .../MDL/IDPO (Quake1)/gijoe-readme.txt | 146 +- test/models-nonbsd/MDL/IDPO (Quake1)/steg.txt | 66 +- .../MDL/IDPO (Quake1)/tekmechbot.txt | 66 +- test/models-nonbsd/NFF/NFFSense8/credits.txt | 6 +- test/models-nonbsd/OBJ/rifle.source.txt | 52 +- test/models-nonbsd/OBJ/segment.source.txt | 6 +- test/models-nonbsd/README.txt | 4 +- test/models-nonbsd/X/dwarf-Read-Me.txt | 102 +- test/models/3DS/UVTransformTest/note.txt | 20 +- test/models/ASE/MotionCaptureROM.source.txt | 4 +- test/models/BLEND/HUMAN.source.txt | 4 +- test/models/BVH/01_nn.bvh.source.txt | 98 +- .../kwxport_test_vcolors.dae.source.txt | 32 +- .../IRR/warn_dwarf_scaling_is_intended.txt | 6 +- test/models/IRRMesh/credits.txt | 2 +- .../LWO/LWO2/MappingModes/earthCylindric.txt | 8 +- .../MappingModes/earthSpherical.source.txt | 16 +- test/models/LWO/LWO2/concrete.source.txt | 2 +- test/models/LWO/LWO2/uvtest-source.txt | 2 +- test/models/MD2/faerie-source.txt | 46 +- test/models/MD2/sidney-source.txt | 46 +- .../MDL/MDL3 (3DGS A4)/minigun_readme.txt | 10 +- .../MDL5 (3DGS A5)/minigun_mdl5_readme.txt | 10 +- test/models/MS3D/jeep1.readme.txt | 28 +- test/models/Q3D/E-AT-AT.source.txt | 14 +- test/models/Q3D/earth.source.txt | 14 +- test/models/WRL/credits.txt | 4 +- test/models/X/anim_test.txt | 16 +- .../X/kwxport_test_cubewithvcolors.source.txt | 32 +- test/models/X/test.txt | 4 +- test/models/invalid/readme.txt | 62 +- workspaces/xcode3/info.txt | 12 +- 103 files changed, 15343 insertions(+), 15343 deletions(-) diff --git a/code/BoostWorkaround/boost/LICENSE_1_0.txt b/code/BoostWorkaround/boost/LICENSE_1_0.txt index 30aac2cf4..127a5bc39 100644 --- a/code/BoostWorkaround/boost/LICENSE_1_0.txt +++ b/code/BoostWorkaround/boost/LICENSE_1_0.txt @@ -1,23 +1,23 @@ -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/code/BoostWorkaround/boost/foreach.hpp b/code/BoostWorkaround/boost/foreach.hpp index 5b5df6a36..404d325c6 100644 --- a/code/BoostWorkaround/boost/foreach.hpp +++ b/code/BoostWorkaround/boost/foreach.hpp @@ -1,99 +1,99 @@ - -#ifndef BOOST_FOREACH - -/////////////////////////////////////////////////////////////////////////////// -// A stripped down version of FOREACH for -// illustration purposes. NOT FOR GENERAL USE. -// For a complete implementation, see BOOST_FOREACH at -// http://boost-sandbox.sourceforge.net/vault/index.php?directory=eric_niebler -// -// Copyright 2004 Eric Niebler. -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// -// Adapted to Assimp November 29th, 2008 (Alexander Gessler). -// Added code to handle both const and non-const iterators, simplified some -// parts. -/////////////////////////////////////////////////////////////////////////////// - -namespace boost { -namespace foreach_detail { - -/////////////////////////////////////////////////////////////////////////////// -// auto_any - -struct auto_any_base -{ - operator bool() const { return false; } -}; - -template -struct auto_any : auto_any_base -{ - auto_any(T const& t) : item(t) {} - mutable T item; -}; - -template -T& auto_any_cast(auto_any_base const& any) -{ - return static_cast const&>(any).item; -} - -/////////////////////////////////////////////////////////////////////////////// -// FOREACH helper function - -template -auto_any begin(T const& t) -{ - return t.begin(); -} - -template -auto_any end(T const& t) -{ - return t.end(); -} - -// iterator -template -bool done(auto_any_base const& cur, auto_any_base const& end, T&) -{ - typedef typename T::iterator iter_type; - return auto_any_cast(cur) == auto_any_cast(end); -} - -template -void next(auto_any_base const& cur, T&) -{ - ++auto_any_cast(cur); -} - -template -typename T::reference deref(auto_any_base const& cur, T&) -{ - return *auto_any_cast(cur); -} - -template -typename T::const_reference deref(auto_any_base const& cur, const T&) -{ - return *auto_any_cast(cur); -} - -} // end foreach_detail - -/////////////////////////////////////////////////////////////////////////////// -// FOREACH - -#define BOOST_FOREACH(item, container) \ - if(boost::foreach_detail::auto_any_base const& foreach_magic_b = boost::foreach_detail::begin(container)) {} else \ - if(boost::foreach_detail::auto_any_base const& foreach_magic_e = boost::foreach_detail::end(container)) {} else \ - for(;!boost::foreach_detail::done(foreach_magic_b,foreach_magic_e,container); boost::foreach_detail::next(foreach_magic_b,container)) \ - if (bool ugly_and_unique_break = false) {} else \ - for(item = boost::foreach_detail::deref(foreach_magic_b,container); !ugly_and_unique_break; ugly_and_unique_break = true) - -} // end boost - -#endif + +#ifndef BOOST_FOREACH + +/////////////////////////////////////////////////////////////////////////////// +// A stripped down version of FOREACH for +// illustration purposes. NOT FOR GENERAL USE. +// For a complete implementation, see BOOST_FOREACH at +// http://boost-sandbox.sourceforge.net/vault/index.php?directory=eric_niebler +// +// Copyright 2004 Eric Niebler. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// Adapted to Assimp November 29th, 2008 (Alexander Gessler). +// Added code to handle both const and non-const iterators, simplified some +// parts. +/////////////////////////////////////////////////////////////////////////////// + +namespace boost { +namespace foreach_detail { + +/////////////////////////////////////////////////////////////////////////////// +// auto_any + +struct auto_any_base +{ + operator bool() const { return false; } +}; + +template +struct auto_any : auto_any_base +{ + auto_any(T const& t) : item(t) {} + mutable T item; +}; + +template +T& auto_any_cast(auto_any_base const& any) +{ + return static_cast const&>(any).item; +} + +/////////////////////////////////////////////////////////////////////////////// +// FOREACH helper function + +template +auto_any begin(T const& t) +{ + return t.begin(); +} + +template +auto_any end(T const& t) +{ + return t.end(); +} + +// iterator +template +bool done(auto_any_base const& cur, auto_any_base const& end, T&) +{ + typedef typename T::iterator iter_type; + return auto_any_cast(cur) == auto_any_cast(end); +} + +template +void next(auto_any_base const& cur, T&) +{ + ++auto_any_cast(cur); +} + +template +typename T::reference deref(auto_any_base const& cur, T&) +{ + return *auto_any_cast(cur); +} + +template +typename T::const_reference deref(auto_any_base const& cur, const T&) +{ + return *auto_any_cast(cur); +} + +} // end foreach_detail + +/////////////////////////////////////////////////////////////////////////////// +// FOREACH + +#define BOOST_FOREACH(item, container) \ + if(boost::foreach_detail::auto_any_base const& foreach_magic_b = boost::foreach_detail::begin(container)) {} else \ + if(boost::foreach_detail::auto_any_base const& foreach_magic_e = boost::foreach_detail::end(container)) {} else \ + for(;!boost::foreach_detail::done(foreach_magic_b,foreach_magic_e,container); boost::foreach_detail::next(foreach_magic_b,container)) \ + if (bool ugly_and_unique_break = false) {} else \ + for(item = boost::foreach_detail::deref(foreach_magic_b,container); !ugly_and_unique_break; ugly_and_unique_break = true) + +} // end boost + +#endif diff --git a/code/BoostWorkaround/boost/lexical_cast.hpp b/code/BoostWorkaround/boost/lexical_cast.hpp index 7724e4607..af91b011f 100644 --- a/code/BoostWorkaround/boost/lexical_cast.hpp +++ b/code/BoostWorkaround/boost/lexical_cast.hpp @@ -1,26 +1,26 @@ -/// A quick replacement for boost::lexical_cast for all the Boost haters out there - -#ifndef __AI_BOOST_WORKAROUND_LEXICAL_CAST -#define __AI_BOOST_WORKAROUND_LEXICAL_CAST - -#include - -namespace boost -{ - - /// A quick replacement for boost::lexical_cast - should work for all types a stringstream can handle - template - TargetType lexical_cast( const SourceType& source) - { - std::stringstream stream; - TargetType result; - - stream << source; - stream >> result; - return result; - } - -} // namespace boost - -#endif // __AI_BOOST_WORKAROUND_LEXICAL_CAST - +/// A quick replacement for boost::lexical_cast for all the Boost haters out there + +#ifndef __AI_BOOST_WORKAROUND_LEXICAL_CAST +#define __AI_BOOST_WORKAROUND_LEXICAL_CAST + +#include + +namespace boost +{ + + /// A quick replacement for boost::lexical_cast - should work for all types a stringstream can handle + template + TargetType lexical_cast( const SourceType& source) + { + std::stringstream stream; + TargetType result; + + stream << source; + stream >> result; + return result; + } + +} // namespace boost + +#endif // __AI_BOOST_WORKAROUND_LEXICAL_CAST + diff --git a/code/BoostWorkaround/boost/make_shared.hpp b/code/BoostWorkaround/boost/make_shared.hpp index b7b29caa5..d1abb1be6 100644 --- a/code/BoostWorkaround/boost/make_shared.hpp +++ b/code/BoostWorkaround/boost/make_shared.hpp @@ -1,57 +1,57 @@ - -// please note that this replacement implementation does not -// provide the performance benefit of the original, which -// makes only one allocation as opposed to two allocations -// (smart pointer counter and payload) which are usually -// required if object and smart pointer are constructed -// independently. - -#ifndef INCLUDED_AI_BOOST_MAKE_SHARED -#define INCLUDED_AI_BOOST_MAKE_SHARED - - -namespace boost { - - template - shared_ptr make_shared() { - return shared_ptr(new T()); - } - - template - shared_ptr make_shared(const T0& t0) { - return shared_ptr(new T(t0)); - } - - template - shared_ptr make_shared(const T0& t0, const T1& t1) { - return shared_ptr(new T(t0,t1)); - } - - template - shared_ptr make_shared(const T0& t0, const T1& t1, const T2& t2) { - return shared_ptr(new T(t0,t1,t2)); - } - - template - shared_ptr make_shared(const T0& t0, const T1& t1, const T2& t2, const T3& t3) { - return shared_ptr(new T(t0,t1,t2,t3)); - } - - template - shared_ptr make_shared(const T0& t0, const T1& t1, const T2& t2, const T3& t3, const T4& t4) { - return shared_ptr(new T(t0,t1,t2,t3,t4)); - } - - template - shared_ptr make_shared(const T0& t0, const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5) { - return shared_ptr(new T(t0,t1,t2,t3,t4,t5)); - } - - template - shared_ptr make_shared(const T0& t0, const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6) { - return shared_ptr(new T(t0,t1,t2,t3,t4,t5,t6)); - } -} - - -#endif + +// please note that this replacement implementation does not +// provide the performance benefit of the original, which +// makes only one allocation as opposed to two allocations +// (smart pointer counter and payload) which are usually +// required if object and smart pointer are constructed +// independently. + +#ifndef INCLUDED_AI_BOOST_MAKE_SHARED +#define INCLUDED_AI_BOOST_MAKE_SHARED + + +namespace boost { + + template + shared_ptr make_shared() { + return shared_ptr(new T()); + } + + template + shared_ptr make_shared(const T0& t0) { + return shared_ptr(new T(t0)); + } + + template + shared_ptr make_shared(const T0& t0, const T1& t1) { + return shared_ptr(new T(t0,t1)); + } + + template + shared_ptr make_shared(const T0& t0, const T1& t1, const T2& t2) { + return shared_ptr(new T(t0,t1,t2)); + } + + template + shared_ptr make_shared(const T0& t0, const T1& t1, const T2& t2, const T3& t3) { + return shared_ptr(new T(t0,t1,t2,t3)); + } + + template + shared_ptr make_shared(const T0& t0, const T1& t1, const T2& t2, const T3& t3, const T4& t4) { + return shared_ptr(new T(t0,t1,t2,t3,t4)); + } + + template + shared_ptr make_shared(const T0& t0, const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5) { + return shared_ptr(new T(t0,t1,t2,t3,t4,t5)); + } + + template + shared_ptr make_shared(const T0& t0, const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6) { + return shared_ptr(new T(t0,t1,t2,t3,t4,t5,t6)); + } +} + + +#endif diff --git a/code/BoostWorkaround/boost/math/common_factor_rt.hpp b/code/BoostWorkaround/boost/math/common_factor_rt.hpp index 46a70a298..f7615f974 100644 --- a/code/BoostWorkaround/boost/math/common_factor_rt.hpp +++ b/code/BoostWorkaround/boost/math/common_factor_rt.hpp @@ -1,37 +1,37 @@ - - -#ifndef BOOST_MATH_COMMON_FACTOR_RT_HPP -#define BOOST_MATH_COMMON_FACTOR_RT_HPP - - -namespace boost { -namespace math { - -// TODO: use binary GCD for unsigned integers .... -template < typename IntegerType > -IntegerType gcd( IntegerType a, IntegerType b ) -{ - const IntegerType zero = (IntegerType)0; - while ( true ) - { - if ( a == zero ) - return b; - b %= a; - - if ( b == zero ) - return a; - a %= b; - } -} - -template < typename IntegerType > -IntegerType lcm( IntegerType a, IntegerType b ) -{ - const IntegerType t = gcd (a,b); - if (!t)return t; - return a / t * b; -} - -}} - -#endif + + +#ifndef BOOST_MATH_COMMON_FACTOR_RT_HPP +#define BOOST_MATH_COMMON_FACTOR_RT_HPP + + +namespace boost { +namespace math { + +// TODO: use binary GCD for unsigned integers .... +template < typename IntegerType > +IntegerType gcd( IntegerType a, IntegerType b ) +{ + const IntegerType zero = (IntegerType)0; + while ( true ) + { + if ( a == zero ) + return b; + b %= a; + + if ( b == zero ) + return a; + a %= b; + } +} + +template < typename IntegerType > +IntegerType lcm( IntegerType a, IntegerType b ) +{ + const IntegerType t = gcd (a,b); + if (!t)return t; + return a / t * b; +} + +}} + +#endif diff --git a/code/BoostWorkaround/boost/noncopyable.hpp b/code/BoostWorkaround/boost/noncopyable.hpp index 7deb935fb..7770bdbd3 100644 --- a/code/BoostWorkaround/boost/noncopyable.hpp +++ b/code/BoostWorkaround/boost/noncopyable.hpp @@ -1,36 +1,36 @@ -// Boost noncopyable.hpp header file --------------------------------------// - -// (C) Copyright Beman Dawes 1999-2003. Distributed under the Boost -// Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org/libs/utility for documentation. - -#ifndef BOOST_NONCOPYABLE_HPP_INCLUDED -#define BOOST_NONCOPYABLE_HPP_INCLUDED - -namespace boost { - -// Private copy constructor and copy assignment ensure classes derived from -// class noncopyable cannot be copied. - -// Contributed by Dave Abrahams - -namespace noncopyable_ // protection from unintended ADL -{ - class noncopyable - { - protected: - noncopyable() {} - ~noncopyable() {} - private: // emphasize the following members are private - noncopyable( const noncopyable& ); - const noncopyable& operator=( const noncopyable& ); - }; -} - -typedef noncopyable_::noncopyable noncopyable; - -} // namespace boost - -#endif // BOOST_NONCOPYABLE_HPP_INCLUDED +// Boost noncopyable.hpp header file --------------------------------------// + +// (C) Copyright Beman Dawes 1999-2003. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/utility for documentation. + +#ifndef BOOST_NONCOPYABLE_HPP_INCLUDED +#define BOOST_NONCOPYABLE_HPP_INCLUDED + +namespace boost { + +// Private copy constructor and copy assignment ensure classes derived from +// class noncopyable cannot be copied. + +// Contributed by Dave Abrahams + +namespace noncopyable_ // protection from unintended ADL +{ + class noncopyable + { + protected: + noncopyable() {} + ~noncopyable() {} + private: // emphasize the following members are private + noncopyable( const noncopyable& ); + const noncopyable& operator=( const noncopyable& ); + }; +} + +typedef noncopyable_::noncopyable noncopyable; + +} // namespace boost + +#endif // BOOST_NONCOPYABLE_HPP_INCLUDED diff --git a/code/BoostWorkaround/boost/pointer_cast.hpp b/code/BoostWorkaround/boost/pointer_cast.hpp index 1083f599e..6e532ebdd 100644 --- a/code/BoostWorkaround/boost/pointer_cast.hpp +++ b/code/BoostWorkaround/boost/pointer_cast.hpp @@ -1,45 +1,45 @@ -////////////////////////////////////////////////////////////////////////////// -// -// (C) Copyright Ion Gaztanaga 2005. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// -////////////////////////////////////////////////////////////////////////////// - -#ifndef BOOST_POINTER_CAST_HPP -#define BOOST_POINTER_CAST_HPP - -namespace boost { - -//static_pointer_cast overload for raw pointers -template -inline T* static_pointer_cast(U *ptr) -{ - return static_cast(ptr); -} - -//dynamic_pointer_cast overload for raw pointers -template -inline T* dynamic_pointer_cast(U *ptr) -{ - return dynamic_cast(ptr); -} - -//const_pointer_cast overload for raw pointers -template -inline T* const_pointer_cast(U *ptr) -{ - return const_cast(ptr); -} - -//reinterpret_pointer_cast overload for raw pointers -template -inline T* reinterpret_pointer_cast(U *ptr) -{ - return reinterpret_cast(ptr); -} - -} // namespace boost - -#endif //BOOST_POINTER_CAST_HPP +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_POINTER_CAST_HPP +#define BOOST_POINTER_CAST_HPP + +namespace boost { + +//static_pointer_cast overload for raw pointers +template +inline T* static_pointer_cast(U *ptr) +{ + return static_cast(ptr); +} + +//dynamic_pointer_cast overload for raw pointers +template +inline T* dynamic_pointer_cast(U *ptr) +{ + return dynamic_cast(ptr); +} + +//const_pointer_cast overload for raw pointers +template +inline T* const_pointer_cast(U *ptr) +{ + return const_cast(ptr); +} + +//reinterpret_pointer_cast overload for raw pointers +template +inline T* reinterpret_pointer_cast(U *ptr) +{ + return reinterpret_cast(ptr); +} + +} // namespace boost + +#endif //BOOST_POINTER_CAST_HPP diff --git a/code/BoostWorkaround/boost/scoped_array.hpp b/code/BoostWorkaround/boost/scoped_array.hpp index 7b1d8cc42..fb1b11544 100644 --- a/code/BoostWorkaround/boost/scoped_array.hpp +++ b/code/BoostWorkaround/boost/scoped_array.hpp @@ -1,79 +1,79 @@ - -#ifndef __AI_BOOST_SCOPED_ARRAY_INCLUDED -#define __AI_BOOST_SCOPED_ARRAY_INCLUDED - -#ifndef BOOST_SCOPED_ARRAY_HPP_INCLUDED - -namespace boost { - -// small replacement for boost::scoped_array -template -class scoped_array -{ -public: - - // provide a default construtctor - scoped_array() - : ptr(0) - { - } - - // construction from an existing heap object of type T - scoped_array(T* _ptr) - : ptr(_ptr) - { - } - - // automatic destruction of the wrapped object at the - // end of our lifetime - ~scoped_array() - { - delete[] ptr; - } - - inline T* get() - { - return ptr; - } - - inline T* operator-> () - { - return ptr; - } - - inline void reset (T* t = 0) - { - delete[] ptr; - ptr = t; - } - - T & operator[](std::ptrdiff_t i) const - { - return ptr[i]; - } - - void swap(scoped_array & b) - { - std::swap(ptr, b.ptr); - } - -private: - - // encapsulated object pointer - T* ptr; - -}; - -template -inline void swap(scoped_array & a, scoped_array & b) -{ - a.swap(b); -} - -} // end of namespace boost - -#else -# error "scoped_array.h was already included" -#endif -#endif // __AI_BOOST_SCOPED_ARRAY_INCLUDED - + +#ifndef __AI_BOOST_SCOPED_ARRAY_INCLUDED +#define __AI_BOOST_SCOPED_ARRAY_INCLUDED + +#ifndef BOOST_SCOPED_ARRAY_HPP_INCLUDED + +namespace boost { + +// small replacement for boost::scoped_array +template +class scoped_array +{ +public: + + // provide a default construtctor + scoped_array() + : ptr(0) + { + } + + // construction from an existing heap object of type T + scoped_array(T* _ptr) + : ptr(_ptr) + { + } + + // automatic destruction of the wrapped object at the + // end of our lifetime + ~scoped_array() + { + delete[] ptr; + } + + inline T* get() + { + return ptr; + } + + inline T* operator-> () + { + return ptr; + } + + inline void reset (T* t = 0) + { + delete[] ptr; + ptr = t; + } + + T & operator[](std::ptrdiff_t i) const + { + return ptr[i]; + } + + void swap(scoped_array & b) + { + std::swap(ptr, b.ptr); + } + +private: + + // encapsulated object pointer + T* ptr; + +}; + +template +inline void swap(scoped_array & a, scoped_array & b) +{ + a.swap(b); +} + +} // end of namespace boost + +#else +# error "scoped_array.h was already included" +#endif +#endif // __AI_BOOST_SCOPED_ARRAY_INCLUDED + diff --git a/code/BoostWorkaround/boost/scoped_ptr.hpp b/code/BoostWorkaround/boost/scoped_ptr.hpp index 615db640d..80c394def 100644 --- a/code/BoostWorkaround/boost/scoped_ptr.hpp +++ b/code/BoostWorkaround/boost/scoped_ptr.hpp @@ -1,79 +1,79 @@ - -#ifndef __AI_BOOST_SCOPED_PTR_INCLUDED -#define __AI_BOOST_SCOPED_PTR_INCLUDED - -#ifndef BOOST_SCOPED_PTR_HPP_INCLUDED - -namespace boost { - -// small replacement for boost::scoped_ptr -template -class scoped_ptr -{ -public: - - // provide a default construtctor - scoped_ptr() - : ptr(0) - { - } - - // construction from an existing heap object of type T - scoped_ptr(T* _ptr) - : ptr(_ptr) - { - } - - // automatic destruction of the wrapped object at the - // end of our lifetime - ~scoped_ptr() - { - delete ptr; - } - - inline T* get() const - { - return ptr; - } - - inline operator T*() - { - return ptr; - } - - inline T* operator-> () - { - return ptr; - } - - inline void reset (T* t = 0) - { - delete ptr; - ptr = t; - } - - void swap(scoped_ptr & b) - { - std::swap(ptr, b.ptr); - } - -private: - - // encapsulated object pointer - T* ptr; - -}; - -template -inline void swap(scoped_ptr & a, scoped_ptr & b) -{ - a.swap(b); -} - -} // end of namespace boost - -#else -# error "scoped_ptr.h was already included" -#endif -#endif // __AI_BOOST_SCOPED_PTR_INCLUDED - + +#ifndef __AI_BOOST_SCOPED_PTR_INCLUDED +#define __AI_BOOST_SCOPED_PTR_INCLUDED + +#ifndef BOOST_SCOPED_PTR_HPP_INCLUDED + +namespace boost { + +// small replacement for boost::scoped_ptr +template +class scoped_ptr +{ +public: + + // provide a default construtctor + scoped_ptr() + : ptr(0) + { + } + + // construction from an existing heap object of type T + scoped_ptr(T* _ptr) + : ptr(_ptr) + { + } + + // automatic destruction of the wrapped object at the + // end of our lifetime + ~scoped_ptr() + { + delete ptr; + } + + inline T* get() const + { + return ptr; + } + + inline operator T*() + { + return ptr; + } + + inline T* operator-> () + { + return ptr; + } + + inline void reset (T* t = 0) + { + delete ptr; + ptr = t; + } + + void swap(scoped_ptr & b) + { + std::swap(ptr, b.ptr); + } + +private: + + // encapsulated object pointer + T* ptr; + +}; + +template +inline void swap(scoped_ptr & a, scoped_ptr & b) +{ + a.swap(b); +} + +} // end of namespace boost + +#else +# error "scoped_ptr.h was already included" +#endif +#endif // __AI_BOOST_SCOPED_PTR_INCLUDED + diff --git a/code/BoostWorkaround/boost/shared_array.hpp b/code/BoostWorkaround/boost/shared_array.hpp index 2d068d556..9847d9f82 100644 --- a/code/BoostWorkaround/boost/shared_array.hpp +++ b/code/BoostWorkaround/boost/shared_array.hpp @@ -1,228 +1,228 @@ - -#ifndef INCLUDED_AI_BOOST_SHARED_ARRAY -#define INCLUDED_AI_BOOST_SHARED_ARRAY - -#ifndef BOOST_SHARED_ARRAY_HPP_INCLUDED - -// ------------------------------ -// Internal stub -namespace boost { - namespace array_detail { - class controller { - public: - - controller() - : cnt(1) - {} - - public: - - template - controller* decref(T* pt) { - if (--cnt <= 0) { - delete this; - delete[] pt; - } - return NULL; - } - - controller* incref() { - ++cnt; - return this; - } - - long get() const { - return cnt; - } - - private: - long cnt; - }; - - struct empty {}; - - template - struct is_convertible_stub { - - struct yes {char s[1];}; - struct no {char s[2];}; - - static yes foo(DEST*); - static no foo(...); - - enum {result = (sizeof(foo((SRC*)0)) == sizeof(yes) ? 1 : 0)}; - }; - - template struct enable_if {}; - template <> struct enable_if { - typedef empty result; - }; - - template - struct is_convertible : public enable_if::result > { - }; - } - -// ------------------------------ -// Small replacement for boost::shared_array, not threadsafe because no -// atomic reference counter is in use. -// ------------------------------ -template -class shared_array -{ - template friend class shared_array; - - template friend bool operator== (const shared_array& a, const shared_array& b); - template friend bool operator!= (const shared_array& a, const shared_array& b); - template friend bool operator< (const shared_array& a, const shared_array& b); - -public: - - typedef T element_type; - -public: - - // provide a default constructor - shared_array() - : ptr() - , ctr(NULL) - { - } - - // construction from an existing object of type T - explicit shared_array(T* ptr) - : ptr(ptr) - , ctr(ptr ? new array_detail::controller() : NULL) - { - } - - shared_array(const shared_array& r) - : ptr(r.ptr) - , ctr(r.ctr ? r.ctr->incref() : NULL) - { - } - - template - shared_array(const shared_array& r,typename detail::is_convertible::result = detail::empty()) - : ptr(r.ptr) - , ctr(r.ctr ? r.ctr->incref() : NULL) - { - } - - // automatic destruction of the wrapped object when all - // references are freed. - ~shared_array() { - if (ctr) { - ctr = ctr->decref(ptr); - } - } - - shared_array& operator=(const shared_array& r) { - if (this == &r) { - return *this; - } - if (ctr) { - ctr->decref(ptr); - } - ptr = r.ptr; - ctr = ptr?r.ctr->incref():NULL; - return *this; - } - - template - shared_array& operator=(const shared_array& r) { - if (this == &r) { - return *this; - } - if (ctr) { - ctr->decref(ptr); - } - ptr = r.ptr; - ctr = ptr?r.ctr->incref():NULL; - return *this; - } - - // pointer access - inline operator T*() { - return ptr; - } - - inline T* operator-> () const { - return ptr; - } - - // standard semantics - inline T* get() { - return ptr; - } - - T& operator[] (std::ptrdiff_t index) const { - return ptr[index]; - } - - inline const T* get() const { - return ptr; - } - - inline operator bool () const { - return ptr != NULL; - } - - inline bool unique() const { - return use_count() == 1; - } - - inline long use_count() const { - return ctr->get(); - } - - inline void reset (T* t = 0) { - if (ctr) { - ctr->decref(ptr); - } - ptr = t; - ctr = ptr?new array_detail::controller():NULL; - } - - void swap(shared_array & b) { - std::swap(ptr, b.ptr); - std::swap(ctr, b.ctr); - } - - -private: - - // encapsulated object pointer - T* ptr; - - // control block - array_detail::controller* ctr; -}; - -template -inline void swap(shared_array & a, shared_array & b) -{ - a.swap(b); -} - -template -bool operator== (const shared_array& a, const shared_array& b) { - return a.ptr == b.ptr; -} -template -bool operator!= (const shared_array& a, const shared_array& b) { - return a.ptr != b.ptr; -} - -template -bool operator< (const shared_array& a, const shared_array& b) { - return a.ptr < b.ptr; -} - - -} // end of namespace boost - -#else -# error "shared_array.h was already included" -#endif -#endif // INCLUDED_AI_BOOST_SHARED_ARRAY + +#ifndef INCLUDED_AI_BOOST_SHARED_ARRAY +#define INCLUDED_AI_BOOST_SHARED_ARRAY + +#ifndef BOOST_SHARED_ARRAY_HPP_INCLUDED + +// ------------------------------ +// Internal stub +namespace boost { + namespace array_detail { + class controller { + public: + + controller() + : cnt(1) + {} + + public: + + template + controller* decref(T* pt) { + if (--cnt <= 0) { + delete this; + delete[] pt; + } + return NULL; + } + + controller* incref() { + ++cnt; + return this; + } + + long get() const { + return cnt; + } + + private: + long cnt; + }; + + struct empty {}; + + template + struct is_convertible_stub { + + struct yes {char s[1];}; + struct no {char s[2];}; + + static yes foo(DEST*); + static no foo(...); + + enum {result = (sizeof(foo((SRC*)0)) == sizeof(yes) ? 1 : 0)}; + }; + + template struct enable_if {}; + template <> struct enable_if { + typedef empty result; + }; + + template + struct is_convertible : public enable_if::result > { + }; + } + +// ------------------------------ +// Small replacement for boost::shared_array, not threadsafe because no +// atomic reference counter is in use. +// ------------------------------ +template +class shared_array +{ + template friend class shared_array; + + template friend bool operator== (const shared_array& a, const shared_array& b); + template friend bool operator!= (const shared_array& a, const shared_array& b); + template friend bool operator< (const shared_array& a, const shared_array& b); + +public: + + typedef T element_type; + +public: + + // provide a default constructor + shared_array() + : ptr() + , ctr(NULL) + { + } + + // construction from an existing object of type T + explicit shared_array(T* ptr) + : ptr(ptr) + , ctr(ptr ? new array_detail::controller() : NULL) + { + } + + shared_array(const shared_array& r) + : ptr(r.ptr) + , ctr(r.ctr ? r.ctr->incref() : NULL) + { + } + + template + shared_array(const shared_array& r,typename detail::is_convertible::result = detail::empty()) + : ptr(r.ptr) + , ctr(r.ctr ? r.ctr->incref() : NULL) + { + } + + // automatic destruction of the wrapped object when all + // references are freed. + ~shared_array() { + if (ctr) { + ctr = ctr->decref(ptr); + } + } + + shared_array& operator=(const shared_array& r) { + if (this == &r) { + return *this; + } + if (ctr) { + ctr->decref(ptr); + } + ptr = r.ptr; + ctr = ptr?r.ctr->incref():NULL; + return *this; + } + + template + shared_array& operator=(const shared_array& r) { + if (this == &r) { + return *this; + } + if (ctr) { + ctr->decref(ptr); + } + ptr = r.ptr; + ctr = ptr?r.ctr->incref():NULL; + return *this; + } + + // pointer access + inline operator T*() { + return ptr; + } + + inline T* operator-> () const { + return ptr; + } + + // standard semantics + inline T* get() { + return ptr; + } + + T& operator[] (std::ptrdiff_t index) const { + return ptr[index]; + } + + inline const T* get() const { + return ptr; + } + + inline operator bool () const { + return ptr != NULL; + } + + inline bool unique() const { + return use_count() == 1; + } + + inline long use_count() const { + return ctr->get(); + } + + inline void reset (T* t = 0) { + if (ctr) { + ctr->decref(ptr); + } + ptr = t; + ctr = ptr?new array_detail::controller():NULL; + } + + void swap(shared_array & b) { + std::swap(ptr, b.ptr); + std::swap(ctr, b.ctr); + } + + +private: + + // encapsulated object pointer + T* ptr; + + // control block + array_detail::controller* ctr; +}; + +template +inline void swap(shared_array & a, shared_array & b) +{ + a.swap(b); +} + +template +bool operator== (const shared_array& a, const shared_array& b) { + return a.ptr == b.ptr; +} +template +bool operator!= (const shared_array& a, const shared_array& b) { + return a.ptr != b.ptr; +} + +template +bool operator< (const shared_array& a, const shared_array& b) { + return a.ptr < b.ptr; +} + + +} // end of namespace boost + +#else +# error "shared_array.h was already included" +#endif +#endif // INCLUDED_AI_BOOST_SHARED_ARRAY diff --git a/code/BoostWorkaround/boost/static_assert.hpp b/code/BoostWorkaround/boost/static_assert.hpp index 718157622..a533c6fa9 100644 --- a/code/BoostWorkaround/boost/static_assert.hpp +++ b/code/BoostWorkaround/boost/static_assert.hpp @@ -1,20 +1,20 @@ - -#ifndef AI_BOOST_STATIC_ASSERT_INCLUDED -#define AI_BOOST_STATIC_ASSERT_INCLUDED - -#ifndef BOOST_STATIC_ASSERT - -namespace boost { - namespace detail { - - template class static_assertion_failure; - template <> class static_assertion_failure {}; - } -} - - -#define BOOST_STATIC_ASSERT(eval) \ -{boost::detail::static_assertion_failure<(eval)> assert_dummy;(void)assert_dummy;} - -#endif -#endif // !! AI_BOOST_STATIC_ASSERT_INCLUDED + +#ifndef AI_BOOST_STATIC_ASSERT_INCLUDED +#define AI_BOOST_STATIC_ASSERT_INCLUDED + +#ifndef BOOST_STATIC_ASSERT + +namespace boost { + namespace detail { + + template class static_assertion_failure; + template <> class static_assertion_failure {}; + } +} + + +#define BOOST_STATIC_ASSERT(eval) \ +{boost::detail::static_assertion_failure<(eval)> assert_dummy;(void)assert_dummy;} + +#endif +#endif // !! AI_BOOST_STATIC_ASSERT_INCLUDED diff --git a/code/BoostWorkaround/boost/tuple/tuple.hpp b/code/BoostWorkaround/boost/tuple/tuple.hpp index ed5d11861..d196f297d 100644 --- a/code/BoostWorkaround/boost/tuple/tuple.hpp +++ b/code/BoostWorkaround/boost/tuple/tuple.hpp @@ -1,283 +1,283 @@ -// A very small replacement for boost::tuple -// (c) Alexander Gessler, 2008 [alexander.gessler@gmx.net] - -#ifndef BOOST_TUPLE_INCLUDED -#define BOOST_TUPLE_INCLUDED - -namespace boost { - namespace detail { - - // Represents an empty tuple slot (up to 5 supported) - struct nulltype {}; - - // For readable error messages - struct tuple_component_idx_out_of_bounds; - - // To share some code for the const/nonconst versions of the getters - template - struct ConstIf { - typedef T t; - }; - - template - struct ConstIf { - typedef const T t; - }; - - // Predeclare some stuff - template struct value_getter; - - // Helper to obtain the type of a tuple element - template - struct type_getter { - typedef type_getter next_elem_getter; - typedef typename next_elem_getter::type type; - }; - - template - struct type_getter { - typedef T type; - }; - - // Base class for all explicit specializations of list_elem - template - struct list_elem_base { - - // Store template parameters - typedef TNEXT next_type; - typedef T type; - - static const unsigned nidx = NIDX; - }; - - // Represents an element in the tuple component list - template - struct list_elem : list_elem_base{ - - // Real members - T me; - TNEXT next; - - // Get the value of a specific tuple element - template - typename type_getter::type& get () { - value_getter s; - return s(*this); - } - - // Get the value of a specific tuple element - template - const typename type_getter::type& get () const { - value_getter s; - return s(*this); - } - - // Explicit cast - template - operator list_elem () const { - list_elem ret; - ret.me = (T2)me; - ret.next = next; - return ret; - } - - // Recursively compare two elements (last element returns always true) - bool operator == (const list_elem& s) const { - return (me == s.me && next == s.next); - } - }; - - // Represents a non-used tuple element - the very last element processed - template - struct list_elem : list_elem_base { - template struct value_getter { - /* just dummy members to produce readable error messages */ - tuple_component_idx_out_of_bounds operator () (typename ConstIf::t& me); - }; - template struct type_getter { - /* just dummy members to produce readable error messages */ - typedef tuple_component_idx_out_of_bounds type; - }; - - // dummy - list_elem& operator = (const list_elem& /*other*/) { - return *this; - } - - // dummy - bool operator == (const list_elem& other) { - return true; - } - }; - - // Represents the absolute end of the list - typedef list_elem list_end; - - // Helper obtain to query the value of a tuple element - // NOTE: This can't be a nested class as the compiler won't accept a full or - // partial specialization of a nested class of a non-specialized template - template - struct value_getter { - - // calling list_elem - typedef list_elem outer_elem; - - // typedef for the getter for next element - typedef value_getter next_value_getter; - - typename ConstIf::type>::t& - operator () (typename ConstIf::t& me) { - - next_value_getter s; - return s(me.next); - } - }; - - template - struct value_getter { - typedef list_elem outer_elem; - - typename ConstIf::t& operator () (typename ConstIf::t& me) { - return me.me; - } - }; - } - - // A very minimal implementation for up to 5 elements - template - class tuple { - - template - friend class tuple; - - private: - - typedef detail::list_elem > > > > very_long; - - very_long m; - - public: - - // Get a specific tuple element - template - typename detail::type_getter::type& get () { - return m.template get(); - } - - // ... and the const version - template - const typename detail::type_getter::type& get () const { - return m.template get(); - } - - - // comparison operators - bool operator== (const tuple& other) const { - return m == other.m; - } - - // ... and the other way round - bool operator!= (const tuple& other) const { - return !(m == other.m); - } - - // cast to another tuple - all single elements must be convertible - template - operator tuple () const { - tuple s; - s.m = (typename tuple ::very_long)m; - return s; - } - }; - - // Another way to access an element ... - template - inline typename tuple::very_long::template type_getter::type& get ( - tuple& m) { - return m.template get(); - } - - // ... and the const version - template - inline const typename tuple::very_long::template type_getter::type& get ( - const tuple& m) { - return m.template get(); - } - - // Constructs a tuple with 5 elements - template - inline tuple make_tuple (const T0& t0, - const T1& t1,const T2& t2,const T3& t3,const T4& t4) { - - tuple t; - t.template get<0>() = t0; - t.template get<1>() = t1; - t.template get<2>() = t2; - t.template get<3>() = t3; - t.template get<4>() = t4; - return t; - } - - // Constructs a tuple with 4 elements - template - inline tuple make_tuple (const T0& t0, - const T1& t1,const T2& t2,const T3& t3) { - tuple t; - t.template get<0>() = t0; - t.template get<1>() = t1; - t.template get<2>() = t2; - t.template get<3>() = t3; - return t; - } - - // Constructs a tuple with 3 elements - template - inline tuple make_tuple (const T0& t0, - const T1& t1,const T2& t2) { - tuple t; - t.template get<0>() = t0; - t.template get<1>() = t1; - t.template get<2>() = t2; - return t; - } - - // Constructs a tuple with 2 elements - template - inline tuple make_tuple (const T0& t0, - const T1& t1) { - tuple t; - t.template get<0>() = t0; - t.template get<1>() = t1; - return t; - } - - // Constructs a tuple with 1 elements (well ...) - template - inline tuple make_tuple (const T0& t0) { - tuple t; - t.template get<0>() = t0; - return t; - } - - // Constructs a tuple with 0 elements (well ...) - inline tuple <> make_tuple () { - tuple <> t; - return t; - } -} - -#endif // !! BOOST_TUPLE_INCLUDED +// A very small replacement for boost::tuple +// (c) Alexander Gessler, 2008 [alexander.gessler@gmx.net] + +#ifndef BOOST_TUPLE_INCLUDED +#define BOOST_TUPLE_INCLUDED + +namespace boost { + namespace detail { + + // Represents an empty tuple slot (up to 5 supported) + struct nulltype {}; + + // For readable error messages + struct tuple_component_idx_out_of_bounds; + + // To share some code for the const/nonconst versions of the getters + template + struct ConstIf { + typedef T t; + }; + + template + struct ConstIf { + typedef const T t; + }; + + // Predeclare some stuff + template struct value_getter; + + // Helper to obtain the type of a tuple element + template + struct type_getter { + typedef type_getter next_elem_getter; + typedef typename next_elem_getter::type type; + }; + + template + struct type_getter { + typedef T type; + }; + + // Base class for all explicit specializations of list_elem + template + struct list_elem_base { + + // Store template parameters + typedef TNEXT next_type; + typedef T type; + + static const unsigned nidx = NIDX; + }; + + // Represents an element in the tuple component list + template + struct list_elem : list_elem_base{ + + // Real members + T me; + TNEXT next; + + // Get the value of a specific tuple element + template + typename type_getter::type& get () { + value_getter s; + return s(*this); + } + + // Get the value of a specific tuple element + template + const typename type_getter::type& get () const { + value_getter s; + return s(*this); + } + + // Explicit cast + template + operator list_elem () const { + list_elem ret; + ret.me = (T2)me; + ret.next = next; + return ret; + } + + // Recursively compare two elements (last element returns always true) + bool operator == (const list_elem& s) const { + return (me == s.me && next == s.next); + } + }; + + // Represents a non-used tuple element - the very last element processed + template + struct list_elem : list_elem_base { + template struct value_getter { + /* just dummy members to produce readable error messages */ + tuple_component_idx_out_of_bounds operator () (typename ConstIf::t& me); + }; + template struct type_getter { + /* just dummy members to produce readable error messages */ + typedef tuple_component_idx_out_of_bounds type; + }; + + // dummy + list_elem& operator = (const list_elem& /*other*/) { + return *this; + } + + // dummy + bool operator == (const list_elem& other) { + return true; + } + }; + + // Represents the absolute end of the list + typedef list_elem list_end; + + // Helper obtain to query the value of a tuple element + // NOTE: This can't be a nested class as the compiler won't accept a full or + // partial specialization of a nested class of a non-specialized template + template + struct value_getter { + + // calling list_elem + typedef list_elem outer_elem; + + // typedef for the getter for next element + typedef value_getter next_value_getter; + + typename ConstIf::type>::t& + operator () (typename ConstIf::t& me) { + + next_value_getter s; + return s(me.next); + } + }; + + template + struct value_getter { + typedef list_elem outer_elem; + + typename ConstIf::t& operator () (typename ConstIf::t& me) { + return me.me; + } + }; + } + + // A very minimal implementation for up to 5 elements + template + class tuple { + + template + friend class tuple; + + private: + + typedef detail::list_elem > > > > very_long; + + very_long m; + + public: + + // Get a specific tuple element + template + typename detail::type_getter::type& get () { + return m.template get(); + } + + // ... and the const version + template + const typename detail::type_getter::type& get () const { + return m.template get(); + } + + + // comparison operators + bool operator== (const tuple& other) const { + return m == other.m; + } + + // ... and the other way round + bool operator!= (const tuple& other) const { + return !(m == other.m); + } + + // cast to another tuple - all single elements must be convertible + template + operator tuple () const { + tuple s; + s.m = (typename tuple ::very_long)m; + return s; + } + }; + + // Another way to access an element ... + template + inline typename tuple::very_long::template type_getter::type& get ( + tuple& m) { + return m.template get(); + } + + // ... and the const version + template + inline const typename tuple::very_long::template type_getter::type& get ( + const tuple& m) { + return m.template get(); + } + + // Constructs a tuple with 5 elements + template + inline tuple make_tuple (const T0& t0, + const T1& t1,const T2& t2,const T3& t3,const T4& t4) { + + tuple t; + t.template get<0>() = t0; + t.template get<1>() = t1; + t.template get<2>() = t2; + t.template get<3>() = t3; + t.template get<4>() = t4; + return t; + } + + // Constructs a tuple with 4 elements + template + inline tuple make_tuple (const T0& t0, + const T1& t1,const T2& t2,const T3& t3) { + tuple t; + t.template get<0>() = t0; + t.template get<1>() = t1; + t.template get<2>() = t2; + t.template get<3>() = t3; + return t; + } + + // Constructs a tuple with 3 elements + template + inline tuple make_tuple (const T0& t0, + const T1& t1,const T2& t2) { + tuple t; + t.template get<0>() = t0; + t.template get<1>() = t1; + t.template get<2>() = t2; + return t; + } + + // Constructs a tuple with 2 elements + template + inline tuple make_tuple (const T0& t0, + const T1& t1) { + tuple t; + t.template get<0>() = t0; + t.template get<1>() = t1; + return t; + } + + // Constructs a tuple with 1 elements (well ...) + template + inline tuple make_tuple (const T0& t0) { + tuple t; + t.template get<0>() = t0; + return t; + } + + // Constructs a tuple with 0 elements (well ...) + inline tuple <> make_tuple () { + tuple <> t; + return t; + } +} + +#endif // !! BOOST_TUPLE_INCLUDED diff --git a/code/res/resource.h b/code/res/resource.h index 41ce1c5ee..37d39284f 100644 --- a/code/res/resource.h +++ b/code/res/resource.h @@ -1,14 +1,14 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by assimp.rc - -// Nächste Standardwerte für neue Objekte -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 101 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by assimp.rc + +// Nächste Standardwerte für neue Objekte +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/contrib/clipper/License.txt b/contrib/clipper/License.txt index 51acabf74..8e2278cef 100644 --- a/contrib/clipper/License.txt +++ b/contrib/clipper/License.txt @@ -1,29 +1,29 @@ -The Clipper code library, the "Software" (that includes Delphi, C++ & C# -source code, accompanying samples and documentation), has been released -under the following license, terms and conditions: - -Boost Software License - Version 1.0 - August 17th, 2003 -http://www.boost.org/LICENSE_1_0.txt - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - +The Clipper code library, the "Software" (that includes Delphi, C++ & C# +source code, accompanying samples and documentation), has been released +under the following license, terms and conditions: + +Boost Software License - Version 1.0 - August 17th, 2003 +http://www.boost.org/LICENSE_1_0.txt + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + diff --git a/contrib/clipper/clipper.cpp b/contrib/clipper/clipper.cpp index 1efa01df8..b2316ccd5 100644 --- a/contrib/clipper/clipper.cpp +++ b/contrib/clipper/clipper.cpp @@ -1,3448 +1,3448 @@ -/******************************************************************************* -* * -* Author : Angus Johnson * -* Version : 4.8.8 * -* Date : 30 August 2012 * -* Website : http://www.angusj.com * -* Copyright : Angus Johnson 2010-2012 * -* * -* License: * -* Use, modification & distribution is subject to Boost Software License Ver 1. * -* http://www.boost.org/LICENSE_1_0.txt * -* * -* Attributions: * -* The code in this library is an extension of Bala Vatti's clipping algorithm: * -* "A generic solution to polygon clipping" * -* Communications of the ACM, Vol 35, Issue 7 (July 1992) pp 56-63. * -* http://portal.acm.org/citation.cfm?id=129906 * -* * -* Computer graphics and geometric modeling: implementation and algorithms * -* By Max K. Agoston * -* Springer; 1 edition (January 4, 2005) * -* http://books.google.com/books?q=vatti+clipping+agoston * -* * -* See also: * -* "Polygon Offsetting by Computing Winding Numbers" * -* Paper no. DETC2005-85513 pp. 565-575 * -* ASME 2005 International Design Engineering Technical Conferences * -* and Computers and Information in Engineering Conference (IDETC/CIE2005) * -* September 24–28, 2005 , Long Beach, California, USA * -* http://www.me.berkeley.edu/~mcmains/pubs/DAC05OffsetPolygon.pdf * -* * -*******************************************************************************/ - -/******************************************************************************* -* * -* This is a translation of the Delphi Clipper library and the naming style * -* used has retained a Delphi flavour. * -* * -*******************************************************************************/ - -#include "clipper.hpp" -#include -#include -#include -#include -#include -#include -#include - -namespace ClipperLib { - -static long64 const loRange = 0x3FFFFFFF; -static long64 const hiRange = 0x3FFFFFFFFFFFFFFFLL; -static double const pi = 3.141592653589793238; -enum Direction { dRightToLeft, dLeftToRight }; - -#define HORIZONTAL (-1.0E+40) -#define TOLERANCE (1.0e-20) -#define NEAR_ZERO(val) (((val) > -TOLERANCE) && ((val) < TOLERANCE)) -#define NEAR_EQUAL(a, b) NEAR_ZERO((a) - (b)) - -inline long64 Abs(long64 val) -{ - return val < 0 ? -val : val; -} -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -// Int128 class (enables safe math on signed 64bit integers) -// eg Int128 val1((long64)9223372036854775807); //ie 2^63 -1 -// Int128 val2((long64)9223372036854775807); -// Int128 val3 = val1 * val2; -// val3.AsString => "85070591730234615847396907784232501249" (8.5e+37) -//------------------------------------------------------------------------------ - -class Int128 -{ - public: - - Int128(long64 _lo = 0) - { - lo = _lo; - if (lo < 0) hi = -1; else hi = 0; - } - - Int128(const Int128 &val): hi(val.hi), lo(val.lo){} - - long64 operator = (const long64 &val) - { - lo = val; - if (lo < 0) hi = -1; else hi = 0; - return val; - } - - bool operator == (const Int128 &val) const - {return (hi == val.hi && lo == val.lo);} - - bool operator != (const Int128 &val) const - { return !(*this == val);} - - bool operator > (const Int128 &val) const - { - if (hi != val.hi) - return hi > val.hi; - else - return lo > val.lo; - } - - bool operator < (const Int128 &val) const - { - if (hi != val.hi) - return hi < val.hi; - else - return lo < val.lo; - } - - bool operator >= (const Int128 &val) const - { return !(*this < val);} - - bool operator <= (const Int128 &val) const - { return !(*this > val);} - - Int128& operator += (const Int128 &rhs) - { - hi += rhs.hi; - lo += rhs.lo; - if (ulong64(lo) < ulong64(rhs.lo)) hi++; - return *this; - } - - Int128 operator + (const Int128 &rhs) const - { - Int128 result(*this); - result+= rhs; - return result; - } - - Int128& operator -= (const Int128 &rhs) - { - Int128 tmp(rhs); - Negate(tmp); - *this += tmp; - return *this; - } - - //Int128 operator -() const - //{ - // Int128 result(*this); - // if (result.lo == 0) { - // if (result.hi != 0) result.hi = -1; - // } - // else { - // result.lo = -result.lo; - // result.hi = ~result.hi; - // } - // return result; - //} - - Int128 operator - (const Int128 &rhs) const - { - Int128 result(*this); - result -= rhs; - return result; - } - - Int128 operator * (const Int128 &rhs) const - { - if ( !(hi == 0 || hi == -1) || !(rhs.hi == 0 || rhs.hi == -1)) - throw "Int128 operator*: overflow error"; - bool negate = (hi < 0) != (rhs.hi < 0); - - Int128 tmp(*this); - if (tmp.hi < 0) Negate(tmp); - ulong64 int1Hi = ulong64(tmp.lo) >> 32; - ulong64 int1Lo = ulong64(tmp.lo & 0xFFFFFFFF); - - tmp = rhs; - if (tmp.hi < 0) Negate(tmp); - ulong64 int2Hi = ulong64(tmp.lo) >> 32; - ulong64 int2Lo = ulong64(tmp.lo & 0xFFFFFFFF); - - //nb: see comments in clipper.pas - ulong64 a = int1Hi * int2Hi; - ulong64 b = int1Lo * int2Lo; - ulong64 c = int1Hi * int2Lo + int1Lo * int2Hi; - - tmp.hi = long64(a + (c >> 32)); - tmp.lo = long64(c << 32); - tmp.lo += long64(b); - if (ulong64(tmp.lo) < b) tmp.hi++; - if (negate) Negate(tmp); - return tmp; - } - - Int128 operator/ (const Int128 &rhs) const - { - if (rhs.lo == 0 && rhs.hi == 0) - throw "Int128 operator/: divide by zero"; - bool negate = (rhs.hi < 0) != (hi < 0); - Int128 result(*this), denom(rhs); - if (result.hi < 0) Negate(result); - if (denom.hi < 0) Negate(denom); - if (denom > result) return Int128(0); //result is only a fraction of 1 - Negate(denom); - - Int128 p(0); - for (int i = 0; i < 128; ++i) - { - p.hi = p.hi << 1; - if (p.lo < 0) p.hi++; - p.lo = long64(p.lo) << 1; - if (result.hi < 0) p.lo++; - result.hi = result.hi << 1; - if (result.lo < 0) result.hi++; - result.lo = long64(result.lo) << 1; - Int128 p2(p); - p += denom; - if (p.hi < 0) p = p2; - else result.lo++; - } - if (negate) Negate(result); - return result; - } - - double AsDouble() const - { - const double shift64 = 18446744073709551616.0; //2^64 - const double bit64 = 9223372036854775808.0; - if (hi < 0) - { - Int128 tmp(*this); - Negate(tmp); - if (tmp.lo < 0) - return (double)tmp.lo - bit64 - tmp.hi * shift64; - else - return -(double)tmp.lo - tmp.hi * shift64; - } - else if (lo < 0) - return -(double)lo + bit64 + hi * shift64; - else - return (double)lo + (double)hi * shift64; - } - - //for bug testing ... - //std::string AsString() const - //{ - // std::string result; - // unsigned char r = 0; - // Int128 tmp(0), val(*this); - // if (hi < 0) Negate(val); - // result.resize(50); - // std::string::size_type i = result.size() -1; - // while (val.hi != 0 || val.lo != 0) - // { - // Div10(val, tmp, r); - // result[i--] = char('0' + r); - // val = tmp; - // } - // if (hi < 0) result[i--] = '-'; - // result.erase(0,i+1); - // if (result.size() == 0) result = "0"; - // return result; - //} - -private: - long64 hi; - long64 lo; - - static void Negate(Int128 &val) - { - if (val.lo == 0) { - if (val.hi != 0) val.hi = -val.hi;; - } - else { - val.lo = -val.lo; - val.hi = ~val.hi; - } - } - - //debugging only ... - //void Div10(const Int128 val, Int128& result, unsigned char & remainder) const - //{ - // remainder = 0; - // result = 0; - // for (int i = 63; i >= 0; --i) - // { - // if ((val.hi & ((long64)1 << i)) != 0) - // remainder = char((remainder * 2) + 1); else - // remainder *= char(2); - // if (remainder >= 10) - // { - // result.hi += ((long64)1 << i); - // remainder -= char(10); - // } - // } - // for (int i = 63; i >= 0; --i) - // { - // if ((val.lo & ((long64)1 << i)) != 0) - // remainder = char((remainder * 2) + 1); else - // remainder *= char(2); - // if (remainder >= 10) - // { - // result.lo += ((long64)1 << i); - // remainder -= char(10); - // } - // } - //} -}; - -//------------------------------------------------------------------------------ -//------------------------------------------------------------------------------ - -bool FullRangeNeeded(const Polygon &pts) -{ - bool result = false; - for (Polygon::size_type i = 0; i < pts.size(); ++i) - { - if (Abs(pts[i].X) > hiRange || Abs(pts[i].Y) > hiRange) - throw "Coordinate exceeds range bounds."; - else if (Abs(pts[i].X) > loRange || Abs(pts[i].Y) > loRange) - result = true; - } - return result; -} -//------------------------------------------------------------------------------ - -bool Orientation(const Polygon &poly) -{ - int highI = (int)poly.size() -1; - if (highI < 2) return false; - - int j = 0, jplus, jminus; - for (int i = 0; i <= highI; ++i) - { - if (poly[i].Y < poly[j].Y) continue; - if ((poly[i].Y > poly[j].Y || poly[i].X < poly[j].X)) j = i; - }; - if (j == highI) jplus = 0; - else jplus = j +1; - if (j == 0) jminus = highI; - else jminus = j -1; - - IntPoint vec1, vec2; - //get cross product of vectors of the edges adjacent to highest point ... - vec1.X = poly[j].X - poly[jminus].X; - vec1.Y = poly[j].Y - poly[jminus].Y; - vec2.X = poly[jplus].X - poly[j].X; - vec2.Y = poly[jplus].Y - poly[j].Y; - - if (Abs(vec1.X) > loRange || Abs(vec1.Y) > loRange || - Abs(vec2.X) > loRange || Abs(vec2.Y) > loRange) - { - if (Abs(vec1.X) > hiRange || Abs(vec1.Y) > hiRange || - Abs(vec2.X) > hiRange || Abs(vec2.Y) > hiRange) - throw "Coordinate exceeds range bounds."; - Int128 cross = Int128(vec1.X) * Int128(vec2.Y) - - Int128(vec2.X) * Int128(vec1.Y); - return cross >= 0; - } - else - return (vec1.X * vec2.Y - vec2.X * vec1.Y) >= 0; -} -//------------------------------------------------------------------------------ - -inline bool PointsEqual( const IntPoint &pt1, const IntPoint &pt2) -{ - return ( pt1.X == pt2.X && pt1.Y == pt2.Y ); -} -//------------------------------------------------------------------------------ - -bool Orientation(OutRec *outRec, bool UseFullInt64Range) -{ - //first make sure bottomPt is correctly assigned ... - OutPt *opBottom = outRec->pts, *op = outRec->pts->next; - while (op != outRec->pts) - { - if (op->pt.Y >= opBottom->pt.Y) - { - if (op->pt.Y > opBottom->pt.Y || op->pt.X < opBottom->pt.X) - opBottom = op; - } - op = op->next; - } - outRec->bottomPt = opBottom; - opBottom->idx = outRec->idx; - - op = opBottom; - //find vertices either side of bottomPt (skipping duplicate points) .... - OutPt *opPrev = op->prev; - OutPt *opNext = op->next; - while (op != opPrev && PointsEqual(op->pt, opPrev->pt)) - opPrev = opPrev->prev; - while (op != opNext && PointsEqual(op->pt, opNext->pt)) - opNext = opNext->next; - - IntPoint ip1, ip2; - ip1.X = op->pt.X - opPrev->pt.X; - ip1.Y = op->pt.Y - opPrev->pt.Y; - ip2.X = opNext->pt.X - op->pt.X; - ip2.Y = opNext->pt.Y - op->pt.Y; - - if (UseFullInt64Range) - return Int128(ip1.X) * Int128(ip2.Y) - Int128(ip2.X) * Int128(ip1.Y) >= 0; - else - return (ip1.X * ip2.Y - ip2.X * ip1.Y) >= 0; -} -//------------------------------------------------------------------------------ - -double Area(const Polygon &poly) -{ - int highI = (int)poly.size() -1; - if (highI < 2) return 0; - - if (FullRangeNeeded(poly)) { - Int128 a; - a = (Int128(poly[highI].X) * Int128(poly[0].Y)) - - Int128(poly[0].X) * Int128(poly[highI].Y); - for (int i = 0; i < highI; ++i) - a += Int128(poly[i].X) * Int128(poly[i+1].Y) - - Int128(poly[i+1].X) * Int128(poly[i].Y); - return a.AsDouble() / 2; - } - else - { - double a; - a = (double)poly[highI].X * poly[0].Y - (double)poly[0].X * poly[highI].Y; - for (int i = 0; i < highI; ++i) - a += (double)poly[i].X * poly[i+1].Y - (double)poly[i+1].X * poly[i].Y; - return a/2; - } -} -//------------------------------------------------------------------------------ - -double Area(const OutRec &outRec, bool UseFullInt64Range) -{ - OutPt *op = outRec.pts; - if (UseFullInt64Range) { - Int128 a(0); - do { - a += (Int128(op->prev->pt.X) * Int128(op->pt.Y)) - - Int128(op->pt.X) * Int128(op->prev->pt.Y); - op = op->next; - } while (op != outRec.pts); - return a.AsDouble() / 2; - } - else - { - double a = 0; - do { - a += (op->prev->pt.X * op->pt.Y) - (op->pt.X * op->prev->pt.Y); - op = op->next; - } while (op != outRec.pts); - return a/2; - } -} -//------------------------------------------------------------------------------ - -bool PointIsVertex(const IntPoint &pt, OutPt *pp) -{ - OutPt *pp2 = pp; - do - { - if (PointsEqual(pp2->pt, pt)) return true; - pp2 = pp2->next; - } - while (pp2 != pp); - return false; -} -//------------------------------------------------------------------------------ - -bool PointInPolygon(const IntPoint &pt, OutPt *pp, bool UseFullInt64Range) -{ - OutPt *pp2 = pp; - bool result = false; - if (UseFullInt64Range) { - do - { - if ((((pp2->pt.Y <= pt.Y) && (pt.Y < pp2->prev->pt.Y)) || - ((pp2->prev->pt.Y <= pt.Y) && (pt.Y < pp2->pt.Y))) && - Int128(pt.X - pp2->pt.X) < (Int128(pp2->prev->pt.X - pp2->pt.X) * - Int128(pt.Y - pp2->pt.Y)) / Int128(pp2->prev->pt.Y - pp2->pt.Y)) - result = !result; - pp2 = pp2->next; - } - while (pp2 != pp); - } - else - { - do - { - if ((((pp2->pt.Y <= pt.Y) && (pt.Y < pp2->prev->pt.Y)) || - ((pp2->prev->pt.Y <= pt.Y) && (pt.Y < pp2->pt.Y))) && - (pt.X < (pp2->prev->pt.X - pp2->pt.X) * (pt.Y - pp2->pt.Y) / - (pp2->prev->pt.Y - pp2->pt.Y) + pp2->pt.X )) result = !result; - pp2 = pp2->next; - } - while (pp2 != pp); - } - return result; -} -//------------------------------------------------------------------------------ - -bool SlopesEqual(TEdge &e1, TEdge &e2, bool UseFullInt64Range) -{ - if (UseFullInt64Range) - return Int128(e1.ytop - e1.ybot) * Int128(e2.xtop - e2.xbot) == - Int128(e1.xtop - e1.xbot) * Int128(e2.ytop - e2.ybot); - else return (e1.ytop - e1.ybot)*(e2.xtop - e2.xbot) == - (e1.xtop - e1.xbot)*(e2.ytop - e2.ybot); -} -//------------------------------------------------------------------------------ - -bool SlopesEqual(const IntPoint pt1, const IntPoint pt2, - const IntPoint pt3, bool UseFullInt64Range) -{ - if (UseFullInt64Range) - return Int128(pt1.Y-pt2.Y) * Int128(pt2.X-pt3.X) == - Int128(pt1.X-pt2.X) * Int128(pt2.Y-pt3.Y); - else return (pt1.Y-pt2.Y)*(pt2.X-pt3.X) == (pt1.X-pt2.X)*(pt2.Y-pt3.Y); -} -//------------------------------------------------------------------------------ - -bool SlopesEqual(const IntPoint pt1, const IntPoint pt2, - const IntPoint pt3, const IntPoint pt4, bool UseFullInt64Range) -{ - if (UseFullInt64Range) - return Int128(pt1.Y-pt2.Y) * Int128(pt3.X-pt4.X) == - Int128(pt1.X-pt2.X) * Int128(pt3.Y-pt4.Y); - else return (pt1.Y-pt2.Y)*(pt3.X-pt4.X) == (pt1.X-pt2.X)*(pt3.Y-pt4.Y); -} -//------------------------------------------------------------------------------ - -double GetDx(const IntPoint pt1, const IntPoint pt2) -{ - return (pt1.Y == pt2.Y) ? - HORIZONTAL : (double)(pt2.X - pt1.X) / (double)(pt2.Y - pt1.Y); -} -//--------------------------------------------------------------------------- - -void SetDx(TEdge &e) -{ - if (e.ybot == e.ytop) e.dx = HORIZONTAL; - else e.dx = (double)(e.xtop - e.xbot) / (double)(e.ytop - e.ybot); -} -//--------------------------------------------------------------------------- - -void SwapSides(TEdge &edge1, TEdge &edge2) -{ - EdgeSide side = edge1.side; - edge1.side = edge2.side; - edge2.side = side; -} -//------------------------------------------------------------------------------ - -void SwapPolyIndexes(TEdge &edge1, TEdge &edge2) -{ - int outIdx = edge1.outIdx; - edge1.outIdx = edge2.outIdx; - edge2.outIdx = outIdx; -} -//------------------------------------------------------------------------------ - -inline long64 Round(double val) -{ - return (val < 0) ? - static_cast(val - 0.5) : static_cast(val + 0.5); -} -//------------------------------------------------------------------------------ - -long64 TopX(TEdge &edge, const long64 currentY) -{ - return ( currentY == edge.ytop ) ? - edge.xtop : edge.xbot + Round(edge.dx *(currentY - edge.ybot)); -} -//------------------------------------------------------------------------------ - -long64 TopX(const IntPoint pt1, const IntPoint pt2, const long64 currentY) -{ - //preconditions: pt1.Y <> pt2.Y and pt1.Y > pt2.Y - if (currentY >= pt1.Y) return pt1.X; - else if (currentY == pt2.Y) return pt2.X; - else if (pt1.X == pt2.X) return pt1.X; - else - { - double q = (double)(pt1.X-pt2.X)/(double)(pt1.Y-pt2.Y); - return Round(pt1.X + (currentY - pt1.Y) *q); - } -} -//------------------------------------------------------------------------------ - -bool IntersectPoint(TEdge &edge1, TEdge &edge2, - IntPoint &ip, bool UseFullInt64Range) -{ - double b1, b2; - if (SlopesEqual(edge1, edge2, UseFullInt64Range)) return false; - else if (NEAR_ZERO(edge1.dx)) - { - ip.X = edge1.xbot; - if (NEAR_EQUAL(edge2.dx, HORIZONTAL)) - { - ip.Y = edge2.ybot; - } else - { - b2 = edge2.ybot - (edge2.xbot/edge2.dx); - ip.Y = Round(ip.X/edge2.dx + b2); - } - } - else if (NEAR_ZERO(edge2.dx)) - { - ip.X = edge2.xbot; - if (NEAR_EQUAL(edge1.dx, HORIZONTAL)) - { - ip.Y = edge1.ybot; - } else - { - b1 = edge1.ybot - (edge1.xbot/edge1.dx); - ip.Y = Round(ip.X/edge1.dx + b1); - } - } else - { - b1 = edge1.xbot - edge1.ybot * edge1.dx; - b2 = edge2.xbot - edge2.ybot * edge2.dx; - b2 = (b2-b1)/(edge1.dx - edge2.dx); - ip.Y = Round(b2); - ip.X = Round(edge1.dx * b2 + b1); - } - - return - //can be *so close* to the top of one edge that the rounded Y equals one ytop ... - (ip.Y == edge1.ytop && ip.Y >= edge2.ytop && edge1.tmpX > edge2.tmpX) || - (ip.Y == edge2.ytop && ip.Y >= edge1.ytop && edge1.tmpX > edge2.tmpX) || - (ip.Y > edge1.ytop && ip.Y > edge2.ytop); -} -//------------------------------------------------------------------------------ - -void ReversePolyPtLinks(OutPt &pp) -{ - OutPt *pp1, *pp2; - pp1 = &pp; - do { - pp2 = pp1->next; - pp1->next = pp1->prev; - pp1->prev = pp2; - pp1 = pp2; - } while( pp1 != &pp ); -} -//------------------------------------------------------------------------------ - -void DisposeOutPts(OutPt*& pp) -{ - if (pp == 0) return; - pp->prev->next = 0; - while( pp ) - { - OutPt *tmpPp = pp; - pp = pp->next; - delete tmpPp ; - } -} -//------------------------------------------------------------------------------ - -void InitEdge(TEdge *e, TEdge *eNext, - TEdge *ePrev, const IntPoint &pt, PolyType polyType) -{ - std::memset( e, 0, sizeof( TEdge )); - - e->next = eNext; - e->prev = ePrev; - e->xcurr = pt.X; - e->ycurr = pt.Y; - if (e->ycurr >= e->next->ycurr) - { - e->xbot = e->xcurr; - e->ybot = e->ycurr; - e->xtop = e->next->xcurr; - e->ytop = e->next->ycurr; - e->windDelta = 1; - } else - { - e->xtop = e->xcurr; - e->ytop = e->ycurr; - e->xbot = e->next->xcurr; - e->ybot = e->next->ycurr; - e->windDelta = -1; - } - SetDx(*e); - e->polyType = polyType; - e->outIdx = -1; -} -//------------------------------------------------------------------------------ - -inline void SwapX(TEdge &e) -{ - //swap horizontal edges' top and bottom x's so they follow the natural - //progression of the bounds - ie so their xbots will align with the - //adjoining lower edge. [Helpful in the ProcessHorizontal() method.] - e.xcurr = e.xtop; - e.xtop = e.xbot; - e.xbot = e.xcurr; -} -//------------------------------------------------------------------------------ - -void SwapPoints(IntPoint &pt1, IntPoint &pt2) -{ - IntPoint tmp = pt1; - pt1 = pt2; - pt2 = tmp; -} -//------------------------------------------------------------------------------ - -bool GetOverlapSegment(IntPoint pt1a, IntPoint pt1b, IntPoint pt2a, - IntPoint pt2b, IntPoint &pt1, IntPoint &pt2) -{ - //precondition: segments are colinear. - if ( pt1a.Y == pt1b.Y || Abs((pt1a.X - pt1b.X)/(pt1a.Y - pt1b.Y)) > 1 ) - { - if (pt1a.X > pt1b.X) SwapPoints(pt1a, pt1b); - if (pt2a.X > pt2b.X) SwapPoints(pt2a, pt2b); - if (pt1a.X > pt2a.X) pt1 = pt1a; else pt1 = pt2a; - if (pt1b.X < pt2b.X) pt2 = pt1b; else pt2 = pt2b; - return pt1.X < pt2.X; - } else - { - if (pt1a.Y < pt1b.Y) SwapPoints(pt1a, pt1b); - if (pt2a.Y < pt2b.Y) SwapPoints(pt2a, pt2b); - if (pt1a.Y < pt2a.Y) pt1 = pt1a; else pt1 = pt2a; - if (pt1b.Y > pt2b.Y) pt2 = pt1b; else pt2 = pt2b; - return pt1.Y > pt2.Y; - } -} -//------------------------------------------------------------------------------ - -bool FirstIsBottomPt(const OutPt* btmPt1, const OutPt* btmPt2) -{ - OutPt *p = btmPt1->prev; - while (PointsEqual(p->pt, btmPt1->pt) && (p != btmPt1)) p = p->prev; - double dx1p = std::fabs(GetDx(btmPt1->pt, p->pt)); - p = btmPt1->next; - while (PointsEqual(p->pt, btmPt1->pt) && (p != btmPt1)) p = p->next; - double dx1n = std::fabs(GetDx(btmPt1->pt, p->pt)); - - p = btmPt2->prev; - while (PointsEqual(p->pt, btmPt2->pt) && (p != btmPt2)) p = p->prev; - double dx2p = std::fabs(GetDx(btmPt2->pt, p->pt)); - p = btmPt2->next; - while (PointsEqual(p->pt, btmPt2->pt) && (p != btmPt2)) p = p->next; - double dx2n = std::fabs(GetDx(btmPt2->pt, p->pt)); - return (dx1p >= dx2p && dx1p >= dx2n) || (dx1n >= dx2p && dx1n >= dx2n); -} -//------------------------------------------------------------------------------ - -OutPt* GetBottomPt(OutPt *pp) -{ - OutPt* dups = 0; - OutPt* p = pp->next; - while (p != pp) - { - if (p->pt.Y > pp->pt.Y) - { - pp = p; - dups = 0; - } - else if (p->pt.Y == pp->pt.Y && p->pt.X <= pp->pt.X) - { - if (p->pt.X < pp->pt.X) - { - dups = 0; - pp = p; - } else - { - if (p->next != pp && p->prev != pp) dups = p; - } - } - p = p->next; - } - if (dups) - { - //there appears to be at least 2 vertices at bottomPt so ... - while (dups != p) - { - if (!FirstIsBottomPt(p, dups)) pp = dups; - dups = dups->next; - while (!PointsEqual(dups->pt, pp->pt)) dups = dups->next; - } - } - return pp; -} -//------------------------------------------------------------------------------ - -bool FindSegment(OutPt* &pp, IntPoint &pt1, IntPoint &pt2) -{ - //outPt1 & outPt2 => the overlap segment (if the function returns true) - if (!pp) return false; - OutPt* pp2 = pp; - IntPoint pt1a = pt1, pt2a = pt2; - do - { - if (SlopesEqual(pt1a, pt2a, pp->pt, pp->prev->pt, true) && - SlopesEqual(pt1a, pt2a, pp->pt, true) && - GetOverlapSegment(pt1a, pt2a, pp->pt, pp->prev->pt, pt1, pt2)) - return true; - pp = pp->next; - } - while (pp != pp2); - return false; -} -//------------------------------------------------------------------------------ - -bool Pt3IsBetweenPt1AndPt2(const IntPoint pt1, - const IntPoint pt2, const IntPoint pt3) -{ - if (PointsEqual(pt1, pt3) || PointsEqual(pt2, pt3)) return true; - else if (pt1.X != pt2.X) return (pt1.X < pt3.X) == (pt3.X < pt2.X); - else return (pt1.Y < pt3.Y) == (pt3.Y < pt2.Y); -} -//------------------------------------------------------------------------------ - -OutPt* InsertPolyPtBetween(OutPt* p1, OutPt* p2, const IntPoint pt) -{ - if (p1 == p2) throw "JoinError"; - OutPt* result = new OutPt; - result->pt = pt; - if (p2 == p1->next) - { - p1->next = result; - p2->prev = result; - result->next = p2; - result->prev = p1; - } else - { - p2->next = result; - p1->prev = result; - result->next = p1; - result->prev = p2; - } - return result; -} - -//------------------------------------------------------------------------------ -// ClipperBase class methods ... -//------------------------------------------------------------------------------ - -ClipperBase::ClipperBase() //constructor -{ - m_MinimaList = 0; - m_CurrentLM = 0; - m_UseFullRange = true; -} -//------------------------------------------------------------------------------ - -ClipperBase::~ClipperBase() //destructor -{ - Clear(); -} -//------------------------------------------------------------------------------ - -bool ClipperBase::AddPolygon( const Polygon &pg, PolyType polyType) -{ - int len = (int)pg.size(); - if (len < 3) return false; - Polygon p(len); - p[0] = pg[0]; - int j = 0; - - long64 maxVal; - if (m_UseFullRange) maxVal = hiRange; else maxVal = loRange; - - for (int i = 0; i < len; ++i) - { - if (Abs(pg[i].X) > maxVal || Abs(pg[i].Y) > maxVal) - { - if (Abs(pg[i].X) > hiRange || Abs(pg[i].Y) > hiRange) - throw "Coordinate exceeds range bounds"; - maxVal = hiRange; - m_UseFullRange = true; - } - - if (i == 0 || PointsEqual(p[j], pg[i])) continue; - else if (j > 0 && SlopesEqual(p[j-1], p[j], pg[i], m_UseFullRange)) - { - if (PointsEqual(p[j-1], pg[i])) j--; - } else j++; - p[j] = pg[i]; - } - if (j < 2) return false; - - len = j+1; - while (len > 2) - { - //nb: test for point equality before testing slopes ... - if (PointsEqual(p[j], p[0])) j--; - else if (PointsEqual(p[0], p[1]) || - SlopesEqual(p[j], p[0], p[1], m_UseFullRange)) - p[0] = p[j--]; - else if (SlopesEqual(p[j-1], p[j], p[0], m_UseFullRange)) j--; - else if (SlopesEqual(p[0], p[1], p[2], m_UseFullRange)) - { - for (int i = 2; i <= j; ++i) p[i-1] = p[i]; - j--; - } - else break; - len--; - } - if (len < 3) return false; - - //create a new edge array ... - TEdge *edges = new TEdge [len]; - m_edges.push_back(edges); - - //convert vertices to a double-linked-list of edges and initialize ... - edges[0].xcurr = p[0].X; - edges[0].ycurr = p[0].Y; - InitEdge(&edges[len-1], &edges[0], &edges[len-2], p[len-1], polyType); - for (int i = len-2; i > 0; --i) - InitEdge(&edges[i], &edges[i+1], &edges[i-1], p[i], polyType); - InitEdge(&edges[0], &edges[1], &edges[len-1], p[0], polyType); - - //reset xcurr & ycurr and find 'eHighest' (given the Y axis coordinates - //increase downward so the 'highest' edge will have the smallest ytop) ... - TEdge *e = &edges[0]; - TEdge *eHighest = e; - do - { - e->xcurr = e->xbot; - e->ycurr = e->ybot; - if (e->ytop < eHighest->ytop) eHighest = e; - e = e->next; - } - while ( e != &edges[0]); - - //make sure eHighest is positioned so the following loop works safely ... - if (eHighest->windDelta > 0) eHighest = eHighest->next; - if (NEAR_EQUAL(eHighest->dx, HORIZONTAL)) eHighest = eHighest->next; - - //finally insert each local minima ... - e = eHighest; - do { - e = AddBoundsToLML(e); - } - while( e != eHighest ); - return true; -} -//------------------------------------------------------------------------------ - -void ClipperBase::InsertLocalMinima(LocalMinima *newLm) -{ - if( ! m_MinimaList ) - { - m_MinimaList = newLm; - } - else if( newLm->Y >= m_MinimaList->Y ) - { - newLm->next = m_MinimaList; - m_MinimaList = newLm; - } else - { - LocalMinima* tmpLm = m_MinimaList; - while( tmpLm->next && ( newLm->Y < tmpLm->next->Y ) ) - tmpLm = tmpLm->next; - newLm->next = tmpLm->next; - tmpLm->next = newLm; - } -} -//------------------------------------------------------------------------------ - -TEdge* ClipperBase::AddBoundsToLML(TEdge *e) -{ - //Starting at the top of one bound we progress to the bottom where there's - //a local minima. We then go to the top of the next bound. These two bounds - //form the left and right (or right and left) bounds of the local minima. - e->nextInLML = 0; - e = e->next; - for (;;) - { - if (NEAR_EQUAL(e->dx, HORIZONTAL)) - { - //nb: proceed through horizontals when approaching from their right, - // but break on horizontal minima if approaching from their left. - // This ensures 'local minima' are always on the left of horizontals. - if (e->next->ytop < e->ytop && e->next->xbot > e->prev->xbot) break; - if (e->xtop != e->prev->xbot) SwapX(*e); - e->nextInLML = e->prev; - } - else if (e->ycurr == e->prev->ycurr) break; - else e->nextInLML = e->prev; - e = e->next; - } - - //e and e.prev are now at a local minima ... - LocalMinima* newLm = new LocalMinima; - newLm->next = 0; - newLm->Y = e->prev->ybot; - - if ( NEAR_EQUAL(e->dx, HORIZONTAL) ) //horizontal edges never start a left bound - { - if (e->xbot != e->prev->xbot) SwapX(*e); - newLm->leftBound = e->prev; - newLm->rightBound = e; - } else if (e->dx < e->prev->dx) - { - newLm->leftBound = e->prev; - newLm->rightBound = e; - } else - { - newLm->leftBound = e; - newLm->rightBound = e->prev; - } - newLm->leftBound->side = esLeft; - newLm->rightBound->side = esRight; - InsertLocalMinima( newLm ); - - for (;;) - { - if ( e->next->ytop == e->ytop && !NEAR_EQUAL(e->next->dx, HORIZONTAL) ) break; - e->nextInLML = e->next; - e = e->next; - if ( NEAR_EQUAL(e->dx, HORIZONTAL) && e->xbot != e->prev->xtop) SwapX(*e); - } - return e->next; -} -//------------------------------------------------------------------------------ - -bool ClipperBase::AddPolygons(const Polygons &ppg, PolyType polyType) -{ - bool result = false; - for (Polygons::size_type i = 0; i < ppg.size(); ++i) - if (AddPolygon(ppg[i], polyType)) result = true; - return result; -} -//------------------------------------------------------------------------------ - -void ClipperBase::Clear() -{ - DisposeLocalMinimaList(); - for (EdgeList::size_type i = 0; i < m_edges.size(); ++i) delete [] m_edges[i]; - m_edges.clear(); - m_UseFullRange = false; -} -//------------------------------------------------------------------------------ - -void ClipperBase::Reset() -{ - m_CurrentLM = m_MinimaList; - if( !m_CurrentLM ) return; //ie nothing to process - - //reset all edges ... - LocalMinima* lm = m_MinimaList; - while( lm ) - { - TEdge* e = lm->leftBound; - while( e ) - { - e->xcurr = e->xbot; - e->ycurr = e->ybot; - e->side = esLeft; - e->outIdx = -1; - e = e->nextInLML; - } - e = lm->rightBound; - while( e ) - { - e->xcurr = e->xbot; - e->ycurr = e->ybot; - e->side = esRight; - e->outIdx = -1; - e = e->nextInLML; - } - lm = lm->next; - } -} -//------------------------------------------------------------------------------ - -void ClipperBase::DisposeLocalMinimaList() -{ - while( m_MinimaList ) - { - LocalMinima* tmpLm = m_MinimaList->next; - delete m_MinimaList; - m_MinimaList = tmpLm; - } - m_CurrentLM = 0; -} -//------------------------------------------------------------------------------ - -void ClipperBase::PopLocalMinima() -{ - if( ! m_CurrentLM ) return; - m_CurrentLM = m_CurrentLM->next; -} -//------------------------------------------------------------------------------ - -IntRect ClipperBase::GetBounds() -{ - IntRect result; - LocalMinima* lm = m_MinimaList; - if (!lm) - { - result.left = result.top = result.right = result.bottom = 0; - return result; - } - result.left = lm->leftBound->xbot; - result.top = lm->leftBound->ybot; - result.right = lm->leftBound->xbot; - result.bottom = lm->leftBound->ybot; - while (lm) - { - if (lm->leftBound->ybot > result.bottom) - result.bottom = lm->leftBound->ybot; - TEdge* e = lm->leftBound; - for (;;) { - TEdge* bottomE = e; - while (e->nextInLML) - { - if (e->xbot < result.left) result.left = e->xbot; - if (e->xbot > result.right) result.right = e->xbot; - e = e->nextInLML; - } - if (e->xbot < result.left) result.left = e->xbot; - if (e->xbot > result.right) result.right = e->xbot; - if (e->xtop < result.left) result.left = e->xtop; - if (e->xtop > result.right) result.right = e->xtop; - if (e->ytop < result.top) result.top = e->ytop; - - if (bottomE == lm->leftBound) e = lm->rightBound; - else break; - } - lm = lm->next; - } - return result; -} - - -//------------------------------------------------------------------------------ -// TClipper methods ... -//------------------------------------------------------------------------------ - -Clipper::Clipper() : ClipperBase() //constructor -{ - m_Scanbeam = 0; - m_ActiveEdges = 0; - m_SortedEdges = 0; - m_IntersectNodes = 0; - m_ExecuteLocked = false; - m_UseFullRange = false; - m_ReverseOutput = false; -} -//------------------------------------------------------------------------------ - -Clipper::~Clipper() //destructor -{ - Clear(); - DisposeScanbeamList(); -} -//------------------------------------------------------------------------------ - -void Clipper::Clear() -{ - if (m_edges.size() == 0) return; //avoids problems with ClipperBase destructor - DisposeAllPolyPts(); - ClipperBase::Clear(); -} -//------------------------------------------------------------------------------ - -void Clipper::DisposeScanbeamList() -{ - while ( m_Scanbeam ) { - Scanbeam* sb2 = m_Scanbeam->next; - delete m_Scanbeam; - m_Scanbeam = sb2; - } -} -//------------------------------------------------------------------------------ - -void Clipper::Reset() -{ - ClipperBase::Reset(); - m_Scanbeam = 0; - m_ActiveEdges = 0; - m_SortedEdges = 0; - DisposeAllPolyPts(); - LocalMinima* lm = m_MinimaList; - while (lm) - { - InsertScanbeam(lm->Y); - InsertScanbeam(lm->leftBound->ytop); - lm = lm->next; - } -} -//------------------------------------------------------------------------------ - -bool Clipper::Execute(ClipType clipType, Polygons &solution, - PolyFillType subjFillType, PolyFillType clipFillType) -{ - if( m_ExecuteLocked ) return false; - m_ExecuteLocked = true; - solution.resize(0); - m_SubjFillType = subjFillType; - m_ClipFillType = clipFillType; - m_ClipType = clipType; - bool succeeded = ExecuteInternal(false); - if (succeeded) BuildResult(solution); - m_ExecuteLocked = false; - return succeeded; -} -//------------------------------------------------------------------------------ - -bool Clipper::Execute(ClipType clipType, ExPolygons &solution, - PolyFillType subjFillType, PolyFillType clipFillType) -{ - if( m_ExecuteLocked ) return false; - m_ExecuteLocked = true; - solution.resize(0); - m_SubjFillType = subjFillType; - m_ClipFillType = clipFillType; - m_ClipType = clipType; - bool succeeded = ExecuteInternal(true); - if (succeeded) BuildResultEx(solution); - m_ExecuteLocked = false; - return succeeded; -} -//------------------------------------------------------------------------------ - -bool PolySort(OutRec *or1, OutRec *or2) -{ - if (or1 == or2) return false; - if (!or1->pts || !or2->pts) - { - if (or1->pts != or2->pts) - { - return or1->pts ? true : false; - } - else return false; - } - int i1, i2; - if (or1->isHole) - i1 = or1->FirstLeft->idx; else - i1 = or1->idx; - if (or2->isHole) - i2 = or2->FirstLeft->idx; else - i2 = or2->idx; - int result = i1 - i2; - if (result == 0 && (or1->isHole != or2->isHole)) - { - return or1->isHole ? false : true; - } - else return result < 0; -} -//------------------------------------------------------------------------------ - -OutRec* FindAppendLinkEnd(OutRec *outRec) -{ - while (outRec->AppendLink) outRec = outRec->AppendLink; - return outRec; -} -//------------------------------------------------------------------------------ - -void Clipper::FixHoleLinkage(OutRec *outRec) -{ - OutRec *tmp; - if (outRec->bottomPt) - tmp = m_PolyOuts[outRec->bottomPt->idx]->FirstLeft; - else - tmp = outRec->FirstLeft; - if (outRec == tmp) throw clipperException("HoleLinkage error"); - - if (tmp) - { - if (tmp->AppendLink) tmp = FindAppendLinkEnd(tmp); - if (tmp == outRec) tmp = 0; - else if (tmp->isHole) - { - FixHoleLinkage(tmp); - tmp = tmp->FirstLeft; - } - } - outRec->FirstLeft = tmp; - if (!tmp) outRec->isHole = false; - outRec->AppendLink = 0; -} -//------------------------------------------------------------------------------ - -bool Clipper::ExecuteInternal(bool fixHoleLinkages) -{ - bool succeeded; - try { - Reset(); - if (!m_CurrentLM ) return true; - long64 botY = PopScanbeam(); - do { - InsertLocalMinimaIntoAEL(botY); - ClearHorzJoins(); - ProcessHorizontals(); - long64 topY = PopScanbeam(); - succeeded = ProcessIntersections(botY, topY); - if (!succeeded) break; - ProcessEdgesAtTopOfScanbeam(topY); - botY = topY; - } while( m_Scanbeam ); - } - catch(...) { - succeeded = false; - } - - if (succeeded) - { - //tidy up output polygons and fix orientations where necessary ... - for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) - { - OutRec *outRec = m_PolyOuts[i]; - if (!outRec->pts) continue; - FixupOutPolygon(*outRec); - if (!outRec->pts) continue; - if (outRec->isHole && fixHoleLinkages) FixHoleLinkage(outRec); - - if (outRec->bottomPt == outRec->bottomFlag && - (Orientation(outRec, m_UseFullRange) != (Area(*outRec, m_UseFullRange) > 0))) - DisposeBottomPt(*outRec); - - if (outRec->isHole == - (m_ReverseOutput ^ Orientation(outRec, m_UseFullRange))) - ReversePolyPtLinks(*outRec->pts); - } - - JoinCommonEdges(fixHoleLinkages); - if (fixHoleLinkages) - std::sort(m_PolyOuts.begin(), m_PolyOuts.end(), PolySort); - } - - ClearJoins(); - ClearHorzJoins(); - return succeeded; -} -//------------------------------------------------------------------------------ - -void Clipper::InsertScanbeam(const long64 Y) -{ - if( !m_Scanbeam ) - { - m_Scanbeam = new Scanbeam; - m_Scanbeam->next = 0; - m_Scanbeam->Y = Y; - } - else if( Y > m_Scanbeam->Y ) - { - Scanbeam* newSb = new Scanbeam; - newSb->Y = Y; - newSb->next = m_Scanbeam; - m_Scanbeam = newSb; - } else - { - Scanbeam* sb2 = m_Scanbeam; - while( sb2->next && ( Y <= sb2->next->Y ) ) sb2 = sb2->next; - if( Y == sb2->Y ) return; //ie ignores duplicates - Scanbeam* newSb = new Scanbeam; - newSb->Y = Y; - newSb->next = sb2->next; - sb2->next = newSb; - } -} -//------------------------------------------------------------------------------ - -long64 Clipper::PopScanbeam() -{ - long64 Y = m_Scanbeam->Y; - Scanbeam* sb2 = m_Scanbeam; - m_Scanbeam = m_Scanbeam->next; - delete sb2; - return Y; -} -//------------------------------------------------------------------------------ - -void Clipper::DisposeAllPolyPts(){ - for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) - DisposeOutRec(i); - m_PolyOuts.clear(); -} -//------------------------------------------------------------------------------ - -void Clipper::DisposeOutRec(PolyOutList::size_type index) -{ - OutRec *outRec = m_PolyOuts[index]; - if (outRec->pts) DisposeOutPts(outRec->pts); - delete outRec; - m_PolyOuts[index] = 0; -} -//------------------------------------------------------------------------------ - -void Clipper::SetWindingCount(TEdge &edge) -{ - TEdge *e = edge.prevInAEL; - //find the edge of the same polytype that immediately preceeds 'edge' in AEL - while ( e && e->polyType != edge.polyType ) e = e->prevInAEL; - if ( !e ) - { - edge.windCnt = edge.windDelta; - edge.windCnt2 = 0; - e = m_ActiveEdges; //ie get ready to calc windCnt2 - } else if ( IsEvenOddFillType(edge) ) - { - //EvenOdd filling ... - edge.windCnt = 1; - edge.windCnt2 = e->windCnt2; - e = e->nextInAEL; //ie get ready to calc windCnt2 - } else - { - //nonZero, Positive or Negative filling ... - if ( e->windCnt * e->windDelta < 0 ) - { - if (Abs(e->windCnt) > 1) - { - if (e->windDelta * edge.windDelta < 0) edge.windCnt = e->windCnt; - else edge.windCnt = e->windCnt + edge.windDelta; - } else - edge.windCnt = e->windCnt + e->windDelta + edge.windDelta; - } else - { - if ( Abs(e->windCnt) > 1 && e->windDelta * edge.windDelta < 0) - edge.windCnt = e->windCnt; - else if ( e->windCnt + edge.windDelta == 0 ) - edge.windCnt = e->windCnt; - else edge.windCnt = e->windCnt + edge.windDelta; - } - edge.windCnt2 = e->windCnt2; - e = e->nextInAEL; //ie get ready to calc windCnt2 - } - - //update windCnt2 ... - if ( IsEvenOddAltFillType(edge) ) - { - //EvenOdd filling ... - while ( e != &edge ) - { - edge.windCnt2 = (edge.windCnt2 == 0) ? 1 : 0; - e = e->nextInAEL; - } - } else - { - //nonZero, Positive or Negative filling ... - while ( e != &edge ) - { - edge.windCnt2 += e->windDelta; - e = e->nextInAEL; - } - } -} -//------------------------------------------------------------------------------ - -bool Clipper::IsEvenOddFillType(const TEdge& edge) const -{ - if (edge.polyType == ptSubject) - return m_SubjFillType == pftEvenOdd; else - return m_ClipFillType == pftEvenOdd; -} -//------------------------------------------------------------------------------ - -bool Clipper::IsEvenOddAltFillType(const TEdge& edge) const -{ - if (edge.polyType == ptSubject) - return m_ClipFillType == pftEvenOdd; else - return m_SubjFillType == pftEvenOdd; -} -//------------------------------------------------------------------------------ - -bool Clipper::IsContributing(const TEdge& edge) const -{ - PolyFillType pft, pft2; - if (edge.polyType == ptSubject) - { - pft = m_SubjFillType; - pft2 = m_ClipFillType; - } else - { - pft = m_ClipFillType; - pft2 = m_SubjFillType; - } - - switch(pft) - { - case pftEvenOdd: - case pftNonZero: - if (Abs(edge.windCnt) != 1) return false; - break; - case pftPositive: - if (edge.windCnt != 1) return false; - break; - default: //pftNegative - if (edge.windCnt != -1) return false; - } - - switch(m_ClipType) - { - case ctIntersection: - switch(pft2) - { - case pftEvenOdd: - case pftNonZero: - return (edge.windCnt2 != 0); - case pftPositive: - return (edge.windCnt2 > 0); - default: - return (edge.windCnt2 < 0); - } - case ctUnion: - switch(pft2) - { - case pftEvenOdd: - case pftNonZero: - return (edge.windCnt2 == 0); - case pftPositive: - return (edge.windCnt2 <= 0); - default: - return (edge.windCnt2 >= 0); - } - case ctDifference: - if (edge.polyType == ptSubject) - switch(pft2) - { - case pftEvenOdd: - case pftNonZero: - return (edge.windCnt2 == 0); - case pftPositive: - return (edge.windCnt2 <= 0); - default: - return (edge.windCnt2 >= 0); - } - else - switch(pft2) - { - case pftEvenOdd: - case pftNonZero: - return (edge.windCnt2 != 0); - case pftPositive: - return (edge.windCnt2 > 0); - default: - return (edge.windCnt2 < 0); - } - default: - return true; - } -} -//------------------------------------------------------------------------------ - -void Clipper::AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &pt) -{ - TEdge *e, *prevE; - if( NEAR_EQUAL(e2->dx, HORIZONTAL) || ( e1->dx > e2->dx ) ) - { - AddOutPt( e1, pt ); - e2->outIdx = e1->outIdx; - e1->side = esLeft; - e2->side = esRight; - e = e1; - if (e->prevInAEL == e2) - prevE = e2->prevInAEL; - else - prevE = e->prevInAEL; - } else - { - AddOutPt( e2, pt ); - e1->outIdx = e2->outIdx; - e1->side = esRight; - e2->side = esLeft; - e = e2; - if (e->prevInAEL == e1) - prevE = e1->prevInAEL; - else - prevE = e->prevInAEL; - } - if (prevE && prevE->outIdx >= 0 && - (TopX(*prevE, pt.Y) == TopX(*e, pt.Y)) && - SlopesEqual(*e, *prevE, m_UseFullRange)) - AddJoin(e, prevE, -1, -1); -} -//------------------------------------------------------------------------------ - -void Clipper::AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &pt) -{ - AddOutPt( e1, pt ); - if( e1->outIdx == e2->outIdx ) - { - e1->outIdx = -1; - e2->outIdx = -1; - } - else if (e1->outIdx < e2->outIdx) - AppendPolygon(e1, e2); - else - AppendPolygon(e2, e1); -} -//------------------------------------------------------------------------------ - -void Clipper::AddEdgeToSEL(TEdge *edge) -{ - //SEL pointers in PEdge are reused to build a list of horizontal edges. - //However, we don't need to worry about order with horizontal edge processing. - if( !m_SortedEdges ) - { - m_SortedEdges = edge; - edge->prevInSEL = 0; - edge->nextInSEL = 0; - } - else - { - edge->nextInSEL = m_SortedEdges; - edge->prevInSEL = 0; - m_SortedEdges->prevInSEL = edge; - m_SortedEdges = edge; - } -} -//------------------------------------------------------------------------------ - -void Clipper::CopyAELToSEL() -{ - TEdge* e = m_ActiveEdges; - m_SortedEdges = e; - if (!m_ActiveEdges) return; - m_SortedEdges->prevInSEL = 0; - e = e->nextInAEL; - while ( e ) - { - e->prevInSEL = e->prevInAEL; - e->prevInSEL->nextInSEL = e; - e->nextInSEL = 0; - e = e->nextInAEL; - } -} -//------------------------------------------------------------------------------ - -void Clipper::AddJoin(TEdge *e1, TEdge *e2, int e1OutIdx, int e2OutIdx) -{ - JoinRec* jr = new JoinRec; - if (e1OutIdx >= 0) - jr->poly1Idx = e1OutIdx; else - jr->poly1Idx = e1->outIdx; - jr->pt1a = IntPoint(e1->xcurr, e1->ycurr); - jr->pt1b = IntPoint(e1->xtop, e1->ytop); - if (e2OutIdx >= 0) - jr->poly2Idx = e2OutIdx; else - jr->poly2Idx = e2->outIdx; - jr->pt2a = IntPoint(e2->xcurr, e2->ycurr); - jr->pt2b = IntPoint(e2->xtop, e2->ytop); - m_Joins.push_back(jr); -} -//------------------------------------------------------------------------------ - -void Clipper::ClearJoins() -{ - for (JoinList::size_type i = 0; i < m_Joins.size(); i++) - delete m_Joins[i]; - m_Joins.resize(0); -} -//------------------------------------------------------------------------------ - -void Clipper::AddHorzJoin(TEdge *e, int idx) -{ - HorzJoinRec* hj = new HorzJoinRec; - hj->edge = e; - hj->savedIdx = idx; - m_HorizJoins.push_back(hj); -} -//------------------------------------------------------------------------------ - -void Clipper::ClearHorzJoins() -{ - for (HorzJoinList::size_type i = 0; i < m_HorizJoins.size(); i++) - delete m_HorizJoins[i]; - m_HorizJoins.resize(0); -} -//------------------------------------------------------------------------------ - -void Clipper::InsertLocalMinimaIntoAEL( const long64 botY) -{ - while( m_CurrentLM && ( m_CurrentLM->Y == botY ) ) - { - TEdge* lb = m_CurrentLM->leftBound; - TEdge* rb = m_CurrentLM->rightBound; - - InsertEdgeIntoAEL( lb ); - InsertScanbeam( lb->ytop ); - InsertEdgeIntoAEL( rb ); - - if (IsEvenOddFillType(*lb)) - { - lb->windDelta = 1; - rb->windDelta = 1; - } - else - { - rb->windDelta = -lb->windDelta; - } - SetWindingCount( *lb ); - rb->windCnt = lb->windCnt; - rb->windCnt2 = lb->windCnt2; - - if( NEAR_EQUAL(rb->dx, HORIZONTAL) ) - { - //nb: only rightbounds can have a horizontal bottom edge - AddEdgeToSEL( rb ); - InsertScanbeam( rb->nextInLML->ytop ); - } - else - InsertScanbeam( rb->ytop ); - - if( IsContributing(*lb) ) - AddLocalMinPoly( lb, rb, IntPoint(lb->xcurr, m_CurrentLM->Y) ); - - //if any output polygons share an edge, they'll need joining later ... - if (rb->outIdx >= 0) - { - if (NEAR_EQUAL(rb->dx, HORIZONTAL)) - { - for (HorzJoinList::size_type i = 0; i < m_HorizJoins.size(); ++i) - { - IntPoint pt, pt2; //returned by GetOverlapSegment() but unused here. - HorzJoinRec* hj = m_HorizJoins[i]; - //if horizontals rb and hj.edge overlap, flag for joining later ... - if (GetOverlapSegment(IntPoint(hj->edge->xbot, hj->edge->ybot), - IntPoint(hj->edge->xtop, hj->edge->ytop), - IntPoint(rb->xbot, rb->ybot), - IntPoint(rb->xtop, rb->ytop), pt, pt2)) - AddJoin(hj->edge, rb, hj->savedIdx); - } - } - } - - if( lb->nextInAEL != rb ) - { - if (rb->outIdx >= 0 && rb->prevInAEL->outIdx >= 0 && - SlopesEqual(*rb->prevInAEL, *rb, m_UseFullRange)) - AddJoin(rb, rb->prevInAEL); - - TEdge* e = lb->nextInAEL; - IntPoint pt = IntPoint(lb->xcurr, lb->ycurr); - while( e != rb ) - { - if(!e) throw clipperException("InsertLocalMinimaIntoAEL: missing rightbound!"); - //nb: For calculating winding counts etc, IntersectEdges() assumes - //that param1 will be to the right of param2 ABOVE the intersection ... - IntersectEdges( rb , e , pt , ipNone); //order important here - e = e->nextInAEL; - } - } - PopLocalMinima(); - } -} -//------------------------------------------------------------------------------ - -void Clipper::DeleteFromAEL(TEdge *e) -{ - TEdge* AelPrev = e->prevInAEL; - TEdge* AelNext = e->nextInAEL; - if( !AelPrev && !AelNext && (e != m_ActiveEdges) ) return; //already deleted - if( AelPrev ) AelPrev->nextInAEL = AelNext; - else m_ActiveEdges = AelNext; - if( AelNext ) AelNext->prevInAEL = AelPrev; - e->nextInAEL = 0; - e->prevInAEL = 0; -} -//------------------------------------------------------------------------------ - -void Clipper::DeleteFromSEL(TEdge *e) -{ - TEdge* SelPrev = e->prevInSEL; - TEdge* SelNext = e->nextInSEL; - if( !SelPrev && !SelNext && (e != m_SortedEdges) ) return; //already deleted - if( SelPrev ) SelPrev->nextInSEL = SelNext; - else m_SortedEdges = SelNext; - if( SelNext ) SelNext->prevInSEL = SelPrev; - e->nextInSEL = 0; - e->prevInSEL = 0; -} -//------------------------------------------------------------------------------ - -void Clipper::IntersectEdges(TEdge *e1, TEdge *e2, - const IntPoint &pt, IntersectProtects protects) -{ - //e1 will be to the left of e2 BELOW the intersection. Therefore e1 is before - //e2 in AEL except when e1 is being inserted at the intersection point ... - bool e1stops = !(ipLeft & protects) && !e1->nextInLML && - e1->xtop == pt.X && e1->ytop == pt.Y; - bool e2stops = !(ipRight & protects) && !e2->nextInLML && - e2->xtop == pt.X && e2->ytop == pt.Y; - bool e1Contributing = ( e1->outIdx >= 0 ); - bool e2contributing = ( e2->outIdx >= 0 ); - - //update winding counts... - //assumes that e1 will be to the right of e2 ABOVE the intersection - if ( e1->polyType == e2->polyType ) - { - if ( IsEvenOddFillType( *e1) ) - { - int oldE1WindCnt = e1->windCnt; - e1->windCnt = e2->windCnt; - e2->windCnt = oldE1WindCnt; - } else - { - if (e1->windCnt + e2->windDelta == 0 ) e1->windCnt = -e1->windCnt; - else e1->windCnt += e2->windDelta; - if ( e2->windCnt - e1->windDelta == 0 ) e2->windCnt = -e2->windCnt; - else e2->windCnt -= e1->windDelta; - } - } else - { - if (!IsEvenOddFillType(*e2)) e1->windCnt2 += e2->windDelta; - else e1->windCnt2 = ( e1->windCnt2 == 0 ) ? 1 : 0; - if (!IsEvenOddFillType(*e1)) e2->windCnt2 -= e1->windDelta; - else e2->windCnt2 = ( e2->windCnt2 == 0 ) ? 1 : 0; - } - - PolyFillType e1FillType, e2FillType, e1FillType2, e2FillType2; - if (e1->polyType == ptSubject) - { - e1FillType = m_SubjFillType; - e1FillType2 = m_ClipFillType; - } else - { - e1FillType = m_ClipFillType; - e1FillType2 = m_SubjFillType; - } - if (e2->polyType == ptSubject) - { - e2FillType = m_SubjFillType; - e2FillType2 = m_ClipFillType; - } else - { - e2FillType = m_ClipFillType; - e2FillType2 = m_SubjFillType; - } - - long64 e1Wc, e2Wc; - switch (e1FillType) - { - case pftPositive: e1Wc = e1->windCnt; break; - case pftNegative: e1Wc = -e1->windCnt; break; - default: e1Wc = Abs(e1->windCnt); - } - switch(e2FillType) - { - case pftPositive: e2Wc = e2->windCnt; break; - case pftNegative: e2Wc = -e2->windCnt; break; - default: e2Wc = Abs(e2->windCnt); - } - - if ( e1Contributing && e2contributing ) - { - if ( e1stops || e2stops || - (e1Wc != 0 && e1Wc != 1) || (e2Wc != 0 && e2Wc != 1) || - (e1->polyType != e2->polyType && m_ClipType != ctXor) ) - AddLocalMaxPoly(e1, e2, pt); - else - DoBothEdges( e1, e2, pt ); - } - else if ( e1Contributing ) - { - if ((e2Wc == 0 || e2Wc == 1) && - (m_ClipType != ctIntersection || - e2->polyType == ptSubject || (e2->windCnt2 != 0))) - DoEdge1(e1, e2, pt); - } - else if ( e2contributing ) - { - if ((e1Wc == 0 || e1Wc == 1) && - (m_ClipType != ctIntersection || - e1->polyType == ptSubject || (e1->windCnt2 != 0))) - DoEdge2(e1, e2, pt); - } - else if ( (e1Wc == 0 || e1Wc == 1) && - (e2Wc == 0 || e2Wc == 1) && !e1stops && !e2stops ) - { - //neither edge is currently contributing ... - - long64 e1Wc2, e2Wc2; - switch (e1FillType2) - { - case pftPositive: e1Wc2 = e1->windCnt2; break; - case pftNegative : e1Wc2 = -e1->windCnt2; break; - default: e1Wc2 = Abs(e1->windCnt2); - } - switch (e2FillType2) - { - case pftPositive: e2Wc2 = e2->windCnt2; break; - case pftNegative: e2Wc2 = -e2->windCnt2; break; - default: e2Wc2 = Abs(e2->windCnt2); - } - - if (e1->polyType != e2->polyType) - AddLocalMinPoly(e1, e2, pt); - else if (e1Wc == 1 && e2Wc == 1) - switch( m_ClipType ) { - case ctIntersection: - if (e1Wc2 > 0 && e2Wc2 > 0) - AddLocalMinPoly(e1, e2, pt); - break; - case ctUnion: - if ( e1Wc2 <= 0 && e2Wc2 <= 0 ) - AddLocalMinPoly(e1, e2, pt); - break; - case ctDifference: - if (((e1->polyType == ptClip) && (e1Wc2 > 0) && (e2Wc2 > 0)) || - ((e1->polyType == ptSubject) && (e1Wc2 <= 0) && (e2Wc2 <= 0))) - AddLocalMinPoly(e1, e2, pt); - break; - case ctXor: - AddLocalMinPoly(e1, e2, pt); - } - else - SwapSides( *e1, *e2 ); - } - - if( (e1stops != e2stops) && - ( (e1stops && (e1->outIdx >= 0)) || (e2stops && (e2->outIdx >= 0)) ) ) - { - SwapSides( *e1, *e2 ); - SwapPolyIndexes( *e1, *e2 ); - } - - //finally, delete any non-contributing maxima edges ... - if( e1stops ) DeleteFromAEL( e1 ); - if( e2stops ) DeleteFromAEL( e2 ); -} -//------------------------------------------------------------------------------ - -void Clipper::SetHoleState(TEdge *e, OutRec *outRec) -{ - bool isHole = false; - TEdge *e2 = e->prevInAEL; - while (e2) - { - if (e2->outIdx >= 0) - { - isHole = !isHole; - if (! outRec->FirstLeft) - outRec->FirstLeft = m_PolyOuts[e2->outIdx]; - } - e2 = e2->prevInAEL; - } - if (isHole) outRec->isHole = true; -} -//------------------------------------------------------------------------------ - -OutRec* GetLowermostRec(OutRec *outRec1, OutRec *outRec2) -{ - //work out which polygon fragment has the correct hole state ... - OutPt *outPt1 = outRec1->bottomPt; - OutPt *outPt2 = outRec2->bottomPt; - if (outPt1->pt.Y > outPt2->pt.Y) return outRec1; - else if (outPt1->pt.Y < outPt2->pt.Y) return outRec2; - else if (outPt1->pt.X < outPt2->pt.X) return outRec1; - else if (outPt1->pt.X > outPt2->pt.X) return outRec2; - else if (outPt1->next == outPt1) return outRec2; - else if (outPt2->next == outPt2) return outRec1; - else if (FirstIsBottomPt(outPt1, outPt2)) return outRec1; - else return outRec2; -} -//------------------------------------------------------------------------------ - -bool Param1RightOfParam2(OutRec* outRec1, OutRec* outRec2) -{ - do - { - outRec1 = outRec1->FirstLeft; - if (outRec1 == outRec2) return true; - } while (outRec1); - return false; -} -//------------------------------------------------------------------------------ - -void Clipper::AppendPolygon(TEdge *e1, TEdge *e2) -{ - //get the start and ends of both output polygons ... - OutRec *outRec1 = m_PolyOuts[e1->outIdx]; - OutRec *outRec2 = m_PolyOuts[e2->outIdx]; - - OutRec *holeStateRec; - if (Param1RightOfParam2(outRec1, outRec2)) holeStateRec = outRec2; - else if (Param1RightOfParam2(outRec2, outRec1)) holeStateRec = outRec1; - else holeStateRec = GetLowermostRec(outRec1, outRec2); - - OutPt* p1_lft = outRec1->pts; - OutPt* p1_rt = p1_lft->prev; - OutPt* p2_lft = outRec2->pts; - OutPt* p2_rt = p2_lft->prev; - - EdgeSide side; - //join e2 poly onto e1 poly and delete pointers to e2 ... - if( e1->side == esLeft ) - { - if( e2->side == esLeft ) - { - //z y x a b c - ReversePolyPtLinks(*p2_lft); - p2_lft->next = p1_lft; - p1_lft->prev = p2_lft; - p1_rt->next = p2_rt; - p2_rt->prev = p1_rt; - outRec1->pts = p2_rt; - } else - { - //x y z a b c - p2_rt->next = p1_lft; - p1_lft->prev = p2_rt; - p2_lft->prev = p1_rt; - p1_rt->next = p2_lft; - outRec1->pts = p2_lft; - } - side = esLeft; - } else - { - if( e2->side == esRight ) - { - //a b c z y x - ReversePolyPtLinks( *p2_lft ); - p1_rt->next = p2_rt; - p2_rt->prev = p1_rt; - p2_lft->next = p1_lft; - p1_lft->prev = p2_lft; - } else - { - //a b c x y z - p1_rt->next = p2_lft; - p2_lft->prev = p1_rt; - p1_lft->prev = p2_rt; - p2_rt->next = p1_lft; - } - side = esRight; - } - - if (holeStateRec == outRec2) - { - outRec1->bottomPt = outRec2->bottomPt; - outRec1->bottomPt->idx = outRec1->idx; - if (outRec2->FirstLeft != outRec1) - outRec1->FirstLeft = outRec2->FirstLeft; - outRec1->isHole = outRec2->isHole; - } - outRec2->pts = 0; - outRec2->bottomPt = 0; - outRec2->AppendLink = outRec1; - int OKIdx = e1->outIdx; - int ObsoleteIdx = e2->outIdx; - - e1->outIdx = -1; //nb: safe because we only get here via AddLocalMaxPoly - e2->outIdx = -1; - - TEdge* e = m_ActiveEdges; - while( e ) - { - if( e->outIdx == ObsoleteIdx ) - { - e->outIdx = OKIdx; - e->side = side; - break; - } - e = e->nextInAEL; - } - - for (JoinList::size_type i = 0; i < m_Joins.size(); ++i) - { - if (m_Joins[i]->poly1Idx == ObsoleteIdx) m_Joins[i]->poly1Idx = OKIdx; - if (m_Joins[i]->poly2Idx == ObsoleteIdx) m_Joins[i]->poly2Idx = OKIdx; - } - - for (HorzJoinList::size_type i = 0; i < m_HorizJoins.size(); ++i) - { - if (m_HorizJoins[i]->savedIdx == ObsoleteIdx) - m_HorizJoins[i]->savedIdx = OKIdx; - } - -} -//------------------------------------------------------------------------------ - -OutRec* Clipper::CreateOutRec() -{ - OutRec* result = new OutRec; - result->isHole = false; - result->FirstLeft = 0; - result->AppendLink = 0; - result->pts = 0; - result->bottomPt = 0; - result->sides = esNeither; - result->bottomFlag = 0; - - return result; -} -//------------------------------------------------------------------------------ - -void Clipper::DisposeBottomPt(OutRec &outRec) -{ - OutPt* next = outRec.bottomPt->next; - OutPt* prev = outRec.bottomPt->prev; - if (outRec.pts == outRec.bottomPt) outRec.pts = next; - delete outRec.bottomPt; - next->prev = prev; - prev->next = next; - outRec.bottomPt = next; - FixupOutPolygon(outRec); -} -//------------------------------------------------------------------------------ - -void Clipper::AddOutPt(TEdge *e, const IntPoint &pt) -{ - bool ToFront = (e->side == esLeft); - if( e->outIdx < 0 ) - { - OutRec *outRec = CreateOutRec(); - m_PolyOuts.push_back(outRec); - outRec->idx = (int)m_PolyOuts.size()-1; - e->outIdx = outRec->idx; - OutPt* op = new OutPt; - outRec->pts = op; - outRec->bottomPt = op; - op->pt = pt; - op->idx = outRec->idx; - op->next = op; - op->prev = op; - SetHoleState(e, outRec); - } else - { - OutRec *outRec = m_PolyOuts[e->outIdx]; - OutPt* op = outRec->pts; - if ((ToFront && PointsEqual(pt, op->pt)) || - (!ToFront && PointsEqual(pt, op->prev->pt))) return; - - if ((e->side | outRec->sides) != outRec->sides) - { - //check for 'rounding' artefacts ... - if (outRec->sides == esNeither && pt.Y == op->pt.Y) - { - if (ToFront) - { - if (pt.X == op->pt.X +1) return; //ie wrong side of bottomPt - } - else if (pt.X == op->pt.X -1) return; //ie wrong side of bottomPt - } - - outRec->sides = (EdgeSide)(outRec->sides | e->side); - if (outRec->sides == esBoth) - { - //A vertex from each side has now been added. - //Vertices of one side of an output polygon are quite commonly close to - //or even 'touching' edges of the other side of the output polygon. - //Very occasionally vertices from one side can 'cross' an edge on the - //the other side. The distance 'crossed' is always less that a unit - //and is purely an artefact of coordinate rounding. Nevertheless, this - //results in very tiny self-intersections. Because of the way - //orientation is calculated, even tiny self-intersections can cause - //the Orientation function to return the wrong result. Therefore, it's - //important to ensure that any self-intersections close to BottomPt are - //detected and removed before orientation is assigned. - - OutPt *opBot, *op2; - if (ToFront) - { - opBot = outRec->pts; - op2 = opBot->next; //op2 == right side - if (opBot->pt.Y != op2->pt.Y && opBot->pt.Y != pt.Y && - ((opBot->pt.X - pt.X)/(opBot->pt.Y - pt.Y) < - (opBot->pt.X - op2->pt.X)/(opBot->pt.Y - op2->pt.Y))) - outRec->bottomFlag = opBot; - } else - { - opBot = outRec->pts->prev; - op2 = opBot->prev; //op2 == left side - if (opBot->pt.Y != op2->pt.Y && opBot->pt.Y != pt.Y && - ((opBot->pt.X - pt.X)/(opBot->pt.Y - pt.Y) > - (opBot->pt.X - op2->pt.X)/(opBot->pt.Y - op2->pt.Y))) - outRec->bottomFlag = opBot; - } - } - } - - OutPt* op2 = new OutPt; - op2->pt = pt; - op2->idx = outRec->idx; - if (op2->pt.Y == outRec->bottomPt->pt.Y && - op2->pt.X < outRec->bottomPt->pt.X) - outRec->bottomPt = op2; - op2->next = op; - op2->prev = op->prev; - op2->prev->next = op2; - op->prev = op2; - if (ToFront) outRec->pts = op2; - } -} -//------------------------------------------------------------------------------ - -void Clipper::ProcessHorizontals() -{ - TEdge* horzEdge = m_SortedEdges; - while( horzEdge ) - { - DeleteFromSEL( horzEdge ); - ProcessHorizontal( horzEdge ); - horzEdge = m_SortedEdges; - } -} -//------------------------------------------------------------------------------ - -bool Clipper::IsTopHorz(const long64 XPos) -{ - TEdge* e = m_SortedEdges; - while( e ) - { - if( ( XPos >= std::min(e->xcurr, e->xtop) ) && - ( XPos <= std::max(e->xcurr, e->xtop) ) ) return false; - e = e->nextInSEL; - } - return true; -} -//------------------------------------------------------------------------------ - -bool IsMinima(TEdge *e) -{ - return e && (e->prev->nextInLML != e) && (e->next->nextInLML != e); -} -//------------------------------------------------------------------------------ - -bool IsMaxima(TEdge *e, const long64 Y) -{ - return e && e->ytop == Y && !e->nextInLML; -} -//------------------------------------------------------------------------------ - -bool IsIntermediate(TEdge *e, const long64 Y) -{ - return e->ytop == Y && e->nextInLML; -} -//------------------------------------------------------------------------------ - -TEdge *GetMaximaPair(TEdge *e) -{ - if( !IsMaxima(e->next, e->ytop) || e->next->xtop != e->xtop ) - return e->prev; else - return e->next; -} -//------------------------------------------------------------------------------ - -void Clipper::SwapPositionsInAEL(TEdge *edge1, TEdge *edge2) -{ - if( !edge1->nextInAEL && !edge1->prevInAEL ) return; - if( !edge2->nextInAEL && !edge2->prevInAEL ) return; - - if( edge1->nextInAEL == edge2 ) - { - TEdge* next = edge2->nextInAEL; - if( next ) next->prevInAEL = edge1; - TEdge* prev = edge1->prevInAEL; - if( prev ) prev->nextInAEL = edge2; - edge2->prevInAEL = prev; - edge2->nextInAEL = edge1; - edge1->prevInAEL = edge2; - edge1->nextInAEL = next; - } - else if( edge2->nextInAEL == edge1 ) - { - TEdge* next = edge1->nextInAEL; - if( next ) next->prevInAEL = edge2; - TEdge* prev = edge2->prevInAEL; - if( prev ) prev->nextInAEL = edge1; - edge1->prevInAEL = prev; - edge1->nextInAEL = edge2; - edge2->prevInAEL = edge1; - edge2->nextInAEL = next; - } - else - { - TEdge* next = edge1->nextInAEL; - TEdge* prev = edge1->prevInAEL; - edge1->nextInAEL = edge2->nextInAEL; - if( edge1->nextInAEL ) edge1->nextInAEL->prevInAEL = edge1; - edge1->prevInAEL = edge2->prevInAEL; - if( edge1->prevInAEL ) edge1->prevInAEL->nextInAEL = edge1; - edge2->nextInAEL = next; - if( edge2->nextInAEL ) edge2->nextInAEL->prevInAEL = edge2; - edge2->prevInAEL = prev; - if( edge2->prevInAEL ) edge2->prevInAEL->nextInAEL = edge2; - } - - if( !edge1->prevInAEL ) m_ActiveEdges = edge1; - else if( !edge2->prevInAEL ) m_ActiveEdges = edge2; -} -//------------------------------------------------------------------------------ - -void Clipper::SwapPositionsInSEL(TEdge *edge1, TEdge *edge2) -{ - if( !( edge1->nextInSEL ) && !( edge1->prevInSEL ) ) return; - if( !( edge2->nextInSEL ) && !( edge2->prevInSEL ) ) return; - - if( edge1->nextInSEL == edge2 ) - { - TEdge* next = edge2->nextInSEL; - if( next ) next->prevInSEL = edge1; - TEdge* prev = edge1->prevInSEL; - if( prev ) prev->nextInSEL = edge2; - edge2->prevInSEL = prev; - edge2->nextInSEL = edge1; - edge1->prevInSEL = edge2; - edge1->nextInSEL = next; - } - else if( edge2->nextInSEL == edge1 ) - { - TEdge* next = edge1->nextInSEL; - if( next ) next->prevInSEL = edge2; - TEdge* prev = edge2->prevInSEL; - if( prev ) prev->nextInSEL = edge1; - edge1->prevInSEL = prev; - edge1->nextInSEL = edge2; - edge2->prevInSEL = edge1; - edge2->nextInSEL = next; - } - else - { - TEdge* next = edge1->nextInSEL; - TEdge* prev = edge1->prevInSEL; - edge1->nextInSEL = edge2->nextInSEL; - if( edge1->nextInSEL ) edge1->nextInSEL->prevInSEL = edge1; - edge1->prevInSEL = edge2->prevInSEL; - if( edge1->prevInSEL ) edge1->prevInSEL->nextInSEL = edge1; - edge2->nextInSEL = next; - if( edge2->nextInSEL ) edge2->nextInSEL->prevInSEL = edge2; - edge2->prevInSEL = prev; - if( edge2->prevInSEL ) edge2->prevInSEL->nextInSEL = edge2; - } - - if( !edge1->prevInSEL ) m_SortedEdges = edge1; - else if( !edge2->prevInSEL ) m_SortedEdges = edge2; -} -//------------------------------------------------------------------------------ - -TEdge* GetNextInAEL(TEdge *e, Direction dir) -{ - return dir == dLeftToRight ? e->nextInAEL : e->prevInAEL; -} -//------------------------------------------------------------------------------ - -void Clipper::ProcessHorizontal(TEdge *horzEdge) -{ - Direction dir; - long64 horzLeft, horzRight; - - if( horzEdge->xcurr < horzEdge->xtop ) - { - horzLeft = horzEdge->xcurr; - horzRight = horzEdge->xtop; - dir = dLeftToRight; - } else - { - horzLeft = horzEdge->xtop; - horzRight = horzEdge->xcurr; - dir = dRightToLeft; - } - - TEdge* eMaxPair; - if( horzEdge->nextInLML ) eMaxPair = 0; - else eMaxPair = GetMaximaPair(horzEdge); - - TEdge* e = GetNextInAEL( horzEdge , dir ); - while( e ) - { - TEdge* eNext = GetNextInAEL( e, dir ); - - if (eMaxPair || - ((dir == dLeftToRight) && (e->xcurr <= horzRight)) || - ((dir == dRightToLeft) && (e->xcurr >= horzLeft))) - { - //ok, so far it looks like we're still in range of the horizontal edge - if ( e->xcurr == horzEdge->xtop && !eMaxPair ) - { - if (SlopesEqual(*e, *horzEdge->nextInLML, m_UseFullRange)) - { - //if output polygons share an edge, they'll need joining later ... - if (horzEdge->outIdx >= 0 && e->outIdx >= 0) - AddJoin(horzEdge->nextInLML, e, horzEdge->outIdx); - break; //we've reached the end of the horizontal line - } - else if (e->dx < horzEdge->nextInLML->dx) - //we really have got to the end of the intermediate horz edge so quit. - //nb: More -ve slopes follow more +ve slopes ABOVE the horizontal. - break; - } - - if( e == eMaxPair ) - { - //horzEdge is evidently a maxima horizontal and we've arrived at its end. - if (dir == dLeftToRight) - IntersectEdges(horzEdge, e, IntPoint(e->xcurr, horzEdge->ycurr), ipNone); - else - IntersectEdges(e, horzEdge, IntPoint(e->xcurr, horzEdge->ycurr), ipNone); - if (eMaxPair->outIdx >= 0) throw clipperException("ProcessHorizontal error"); - return; - } - else if( NEAR_EQUAL(e->dx, HORIZONTAL) && !IsMinima(e) && !(e->xcurr > e->xtop) ) - { - //An overlapping horizontal edge. Overlapping horizontal edges are - //processed as if layered with the current horizontal edge (horizEdge) - //being infinitesimally lower that the next (e). Therfore, we - //intersect with e only if e.xcurr is within the bounds of horzEdge ... - if( dir == dLeftToRight ) - IntersectEdges( horzEdge , e, IntPoint(e->xcurr, horzEdge->ycurr), - (IsTopHorz( e->xcurr ))? ipLeft : ipBoth ); - else - IntersectEdges( e, horzEdge, IntPoint(e->xcurr, horzEdge->ycurr), - (IsTopHorz( e->xcurr ))? ipRight : ipBoth ); - } - else if( dir == dLeftToRight ) - { - IntersectEdges( horzEdge, e, IntPoint(e->xcurr, horzEdge->ycurr), - (IsTopHorz( e->xcurr ))? ipLeft : ipBoth ); - } - else - { - IntersectEdges( e, horzEdge, IntPoint(e->xcurr, horzEdge->ycurr), - (IsTopHorz( e->xcurr ))? ipRight : ipBoth ); - } - SwapPositionsInAEL( horzEdge, e ); - } - else if( (dir == dLeftToRight && e->xcurr > horzRight && m_SortedEdges) || - (dir == dRightToLeft && e->xcurr < horzLeft && m_SortedEdges) ) break; - e = eNext; - } //end while - - if( horzEdge->nextInLML ) - { - if( horzEdge->outIdx >= 0 ) - AddOutPt( horzEdge, IntPoint(horzEdge->xtop, horzEdge->ytop)); - UpdateEdgeIntoAEL( horzEdge ); - } - else - { - if ( horzEdge->outIdx >= 0 ) - IntersectEdges( horzEdge, eMaxPair, - IntPoint(horzEdge->xtop, horzEdge->ycurr), ipBoth); - if (eMaxPair->outIdx >= 0) throw clipperException("ProcessHorizontal error"); - DeleteFromAEL(eMaxPair); - DeleteFromAEL(horzEdge); - } -} -//------------------------------------------------------------------------------ - -void Clipper::UpdateEdgeIntoAEL(TEdge *&e) -{ - if( !e->nextInLML ) throw - clipperException("UpdateEdgeIntoAEL: invalid call"); - TEdge* AelPrev = e->prevInAEL; - TEdge* AelNext = e->nextInAEL; - e->nextInLML->outIdx = e->outIdx; - if( AelPrev ) AelPrev->nextInAEL = e->nextInLML; - else m_ActiveEdges = e->nextInLML; - if( AelNext ) AelNext->prevInAEL = e->nextInLML; - e->nextInLML->side = e->side; - e->nextInLML->windDelta = e->windDelta; - e->nextInLML->windCnt = e->windCnt; - e->nextInLML->windCnt2 = e->windCnt2; - e = e->nextInLML; - e->prevInAEL = AelPrev; - e->nextInAEL = AelNext; - if( !NEAR_EQUAL(e->dx, HORIZONTAL) ) InsertScanbeam( e->ytop ); -} -//------------------------------------------------------------------------------ - -bool Clipper::ProcessIntersections(const long64 botY, const long64 topY) -{ - if( !m_ActiveEdges ) return true; - try { - BuildIntersectList(botY, topY); - if ( !m_IntersectNodes) return true; - if ( FixupIntersections() ) ProcessIntersectList(); - else return false; - } - catch(...) { - m_SortedEdges = 0; - DisposeIntersectNodes(); - throw clipperException("ProcessIntersections error"); - } - return true; -} -//------------------------------------------------------------------------------ - -void Clipper::DisposeIntersectNodes() -{ - while ( m_IntersectNodes ) - { - IntersectNode* iNode = m_IntersectNodes->next; - delete m_IntersectNodes; - m_IntersectNodes = iNode; - } -} -//------------------------------------------------------------------------------ - -void Clipper::BuildIntersectList(const long64 botY, const long64 topY) -{ - if ( !m_ActiveEdges ) return; - - //prepare for sorting ... - TEdge* e = m_ActiveEdges; - e->tmpX = TopX( *e, topY ); - m_SortedEdges = e; - m_SortedEdges->prevInSEL = 0; - e = e->nextInAEL; - while( e ) - { - e->prevInSEL = e->prevInAEL; - e->prevInSEL->nextInSEL = e; - e->nextInSEL = 0; - e->tmpX = TopX( *e, topY ); - e = e->nextInAEL; - } - - //bubblesort ... - bool isModified = true; - while( isModified && m_SortedEdges ) - { - isModified = false; - e = m_SortedEdges; - while( e->nextInSEL ) - { - TEdge *eNext = e->nextInSEL; - IntPoint pt; - if(e->tmpX > eNext->tmpX && - IntersectPoint(*e, *eNext, pt, m_UseFullRange)) - { - if (pt.Y > botY) - { - pt.Y = botY; - pt.X = TopX(*e, pt.Y); - } - AddIntersectNode( e, eNext, pt ); - SwapPositionsInSEL(e, eNext); - isModified = true; - } - else - e = eNext; - } - if( e->prevInSEL ) e->prevInSEL->nextInSEL = 0; - else break; - } - m_SortedEdges = 0; -} -//------------------------------------------------------------------------------ - -bool ProcessParam1BeforeParam2(IntersectNode &node1, IntersectNode &node2) -{ - bool result; - if (node1.pt.Y == node2.pt.Y) - { - if (node1.edge1 == node2.edge1 || node1.edge2 == node2.edge1) - { - result = node2.pt.X > node1.pt.X; - return node2.edge1->dx > 0 ? !result : result; - } - else if (node1.edge1 == node2.edge2 || node1.edge2 == node2.edge2) - { - result = node2.pt.X > node1.pt.X; - return node2.edge2->dx > 0 ? !result : result; - } - else return node2.pt.X > node1.pt.X; - } - else return node1.pt.Y > node2.pt.Y; -} -//------------------------------------------------------------------------------ - -void Clipper::AddIntersectNode(TEdge *e1, TEdge *e2, const IntPoint &pt) -{ - IntersectNode* newNode = new IntersectNode; - newNode->edge1 = e1; - newNode->edge2 = e2; - newNode->pt = pt; - newNode->next = 0; - if( !m_IntersectNodes ) m_IntersectNodes = newNode; - else if( ProcessParam1BeforeParam2(*newNode, *m_IntersectNodes) ) - { - newNode->next = m_IntersectNodes; - m_IntersectNodes = newNode; - } - else - { - IntersectNode* iNode = m_IntersectNodes; - while( iNode->next && ProcessParam1BeforeParam2(*iNode->next, *newNode) ) - iNode = iNode->next; - newNode->next = iNode->next; - iNode->next = newNode; - } -} -//------------------------------------------------------------------------------ - -void Clipper::ProcessIntersectList() -{ - while( m_IntersectNodes ) - { - IntersectNode* iNode = m_IntersectNodes->next; - { - IntersectEdges( m_IntersectNodes->edge1 , - m_IntersectNodes->edge2 , m_IntersectNodes->pt, ipBoth ); - SwapPositionsInAEL( m_IntersectNodes->edge1 , m_IntersectNodes->edge2 ); - } - delete m_IntersectNodes; - m_IntersectNodes = iNode; - } -} -//------------------------------------------------------------------------------ - -void Clipper::DoMaxima(TEdge *e, long64 topY) -{ - TEdge* eMaxPair = GetMaximaPair(e); - long64 X = e->xtop; - TEdge* eNext = e->nextInAEL; - while( eNext != eMaxPair ) - { - if (!eNext) throw clipperException("DoMaxima error"); - IntersectEdges( e, eNext, IntPoint(X, topY), ipBoth ); - eNext = eNext->nextInAEL; - } - if( e->outIdx < 0 && eMaxPair->outIdx < 0 ) - { - DeleteFromAEL( e ); - DeleteFromAEL( eMaxPair ); - } - else if( e->outIdx >= 0 && eMaxPair->outIdx >= 0 ) - { - IntersectEdges( e, eMaxPair, IntPoint(X, topY), ipNone ); - } - else throw clipperException("DoMaxima error"); -} -//------------------------------------------------------------------------------ - -void Clipper::ProcessEdgesAtTopOfScanbeam(const long64 topY) -{ - TEdge* e = m_ActiveEdges; - while( e ) - { - //1. process maxima, treating them as if they're 'bent' horizontal edges, - // but exclude maxima with horizontal edges. nb: e can't be a horizontal. - if( IsMaxima(e, topY) && !NEAR_EQUAL(GetMaximaPair(e)->dx, HORIZONTAL) ) - { - //'e' might be removed from AEL, as may any following edges so ... - TEdge* ePrior = e->prevInAEL; - DoMaxima(e, topY); - if( !ePrior ) e = m_ActiveEdges; - else e = ePrior->nextInAEL; - } - else - { - //2. promote horizontal edges, otherwise update xcurr and ycurr ... - if( IsIntermediate(e, topY) && NEAR_EQUAL(e->nextInLML->dx, HORIZONTAL) ) - { - if (e->outIdx >= 0) - { - AddOutPt(e, IntPoint(e->xtop, e->ytop)); - - for (HorzJoinList::size_type i = 0; i < m_HorizJoins.size(); ++i) - { - IntPoint pt, pt2; - HorzJoinRec* hj = m_HorizJoins[i]; - if (GetOverlapSegment(IntPoint(hj->edge->xbot, hj->edge->ybot), - IntPoint(hj->edge->xtop, hj->edge->ytop), - IntPoint(e->nextInLML->xbot, e->nextInLML->ybot), - IntPoint(e->nextInLML->xtop, e->nextInLML->ytop), pt, pt2)) - AddJoin(hj->edge, e->nextInLML, hj->savedIdx, e->outIdx); - } - - AddHorzJoin(e->nextInLML, e->outIdx); - } - UpdateEdgeIntoAEL(e); - AddEdgeToSEL(e); - } else - { - //this just simplifies horizontal processing ... - e->xcurr = TopX( *e, topY ); - e->ycurr = topY; - } - e = e->nextInAEL; - } - } - - //3. Process horizontals at the top of the scanbeam ... - ProcessHorizontals(); - - //4. Promote intermediate vertices ... - e = m_ActiveEdges; - while( e ) - { - if( IsIntermediate( e, topY ) ) - { - if( e->outIdx >= 0 ) AddOutPt(e, IntPoint(e->xtop,e->ytop)); - UpdateEdgeIntoAEL(e); - - //if output polygons share an edge, they'll need joining later ... - if (e->outIdx >= 0 && e->prevInAEL && e->prevInAEL->outIdx >= 0 && - e->prevInAEL->xcurr == e->xbot && e->prevInAEL->ycurr == e->ybot && - SlopesEqual(IntPoint(e->xbot,e->ybot), IntPoint(e->xtop, e->ytop), - IntPoint(e->xbot,e->ybot), - IntPoint(e->prevInAEL->xtop, e->prevInAEL->ytop), m_UseFullRange)) - { - AddOutPt(e->prevInAEL, IntPoint(e->xbot, e->ybot)); - AddJoin(e, e->prevInAEL); - } - else if (e->outIdx >= 0 && e->nextInAEL && e->nextInAEL->outIdx >= 0 && - e->nextInAEL->ycurr > e->nextInAEL->ytop && - e->nextInAEL->ycurr <= e->nextInAEL->ybot && - e->nextInAEL->xcurr == e->xbot && e->nextInAEL->ycurr == e->ybot && - SlopesEqual(IntPoint(e->xbot,e->ybot), IntPoint(e->xtop, e->ytop), - IntPoint(e->xbot,e->ybot), - IntPoint(e->nextInAEL->xtop, e->nextInAEL->ytop), m_UseFullRange)) - { - AddOutPt(e->nextInAEL, IntPoint(e->xbot, e->ybot)); - AddJoin(e, e->nextInAEL); - } - } - e = e->nextInAEL; - } -} -//------------------------------------------------------------------------------ - -void Clipper::FixupOutPolygon(OutRec &outRec) -{ - //FixupOutPolygon() - removes duplicate points and simplifies consecutive - //parallel edges by removing the middle vertex. - OutPt *lastOK = 0; - outRec.pts = outRec.bottomPt; - OutPt *pp = outRec.bottomPt; - - for (;;) - { - if (pp->prev == pp || pp->prev == pp->next ) - { - DisposeOutPts(pp); - outRec.pts = 0; - outRec.bottomPt = 0; - return; - } - //test for duplicate points and for same slope (cross-product) ... - if ( PointsEqual(pp->pt, pp->next->pt) || - SlopesEqual(pp->prev->pt, pp->pt, pp->next->pt, m_UseFullRange) ) - { - lastOK = 0; - OutPt *tmp = pp; - if (pp == outRec.bottomPt) - outRec.bottomPt = 0; //flags need for updating - pp->prev->next = pp->next; - pp->next->prev = pp->prev; - pp = pp->prev; - delete tmp; - } - else if (pp == lastOK) break; - else - { - if (!lastOK) lastOK = pp; - pp = pp->next; - } - } - if (!outRec.bottomPt) { - outRec.bottomPt = GetBottomPt(pp); - outRec.bottomPt->idx = outRec.idx; - outRec.pts = outRec.bottomPt; - } -} -//------------------------------------------------------------------------------ - -void Clipper::BuildResult(Polygons &polys) -{ - int k = 0; - polys.resize(m_PolyOuts.size()); - for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) - { - if (m_PolyOuts[i]->pts) - { - Polygon* pg = &polys[k]; - pg->clear(); - OutPt* p = m_PolyOuts[i]->pts; - do - { - pg->push_back(p->pt); - p = p->next; - } while (p != m_PolyOuts[i]->pts); - //make sure each polygon has at least 3 vertices ... - if (pg->size() < 3) pg->clear(); else k++; - } - } - polys.resize(k); -} -//------------------------------------------------------------------------------ - -void Clipper::BuildResultEx(ExPolygons &polys) -{ - PolyOutList::size_type i = 0; - int k = 0; - polys.resize(0); - polys.reserve(m_PolyOuts.size()); - while (i < m_PolyOuts.size() && m_PolyOuts[i]->pts) - { - ExPolygon epg; - OutPt* p = m_PolyOuts[i]->pts; - do { - epg.outer.push_back(p->pt); - p = p->next; - } while (p != m_PolyOuts[i]->pts); - i++; - //make sure polygons have at least 3 vertices ... - if (epg.outer.size() < 3) continue; - while (i < m_PolyOuts.size() - && m_PolyOuts[i]->pts && m_PolyOuts[i]->isHole) - { - Polygon pg; - p = m_PolyOuts[i]->pts; - do { - pg.push_back(p->pt); - p = p->next; - } while (p != m_PolyOuts[i]->pts); - epg.holes.push_back(pg); - i++; - } - polys.push_back(epg); - k++; - } - polys.resize(k); -} -//------------------------------------------------------------------------------ - -void SwapIntersectNodes(IntersectNode &int1, IntersectNode &int2) -{ - TEdge *e1 = int1.edge1; - TEdge *e2 = int1.edge2; - IntPoint p = int1.pt; - - int1.edge1 = int2.edge1; - int1.edge2 = int2.edge2; - int1.pt = int2.pt; - - int2.edge1 = e1; - int2.edge2 = e2; - int2.pt = p; -} -//------------------------------------------------------------------------------ - -bool Clipper::FixupIntersections() -{ - if ( !m_IntersectNodes->next ) return true; - - CopyAELToSEL(); - IntersectNode *int1 = m_IntersectNodes; - IntersectNode *int2 = m_IntersectNodes->next; - while (int2) - { - TEdge *e1 = int1->edge1; - TEdge *e2; - if (e1->prevInSEL == int1->edge2) e2 = e1->prevInSEL; - else if (e1->nextInSEL == int1->edge2) e2 = e1->nextInSEL; - else - { - //The current intersection is out of order, so try and swap it with - //a subsequent intersection ... - while (int2) - { - if (int2->edge1->nextInSEL == int2->edge2 || - int2->edge1->prevInSEL == int2->edge2) break; - else int2 = int2->next; - } - if ( !int2 ) return false; //oops!!! - - //found an intersect node that can be swapped ... - SwapIntersectNodes(*int1, *int2); - e1 = int1->edge1; - e2 = int1->edge2; - } - SwapPositionsInSEL(e1, e2); - int1 = int1->next; - int2 = int1->next; - } - - m_SortedEdges = 0; - - //finally, check the last intersection too ... - return (int1->edge1->prevInSEL == int1->edge2 || - int1->edge1->nextInSEL == int1->edge2); -} -//------------------------------------------------------------------------------ - -bool E2InsertsBeforeE1(TEdge &e1, TEdge &e2) -{ - return e2.xcurr == e1.xcurr ? e2.dx > e1.dx : e2.xcurr < e1.xcurr; -} -//------------------------------------------------------------------------------ - -void Clipper::InsertEdgeIntoAEL(TEdge *edge) -{ - edge->prevInAEL = 0; - edge->nextInAEL = 0; - if( !m_ActiveEdges ) - { - m_ActiveEdges = edge; - } - else if( E2InsertsBeforeE1(*m_ActiveEdges, *edge) ) - { - edge->nextInAEL = m_ActiveEdges; - m_ActiveEdges->prevInAEL = edge; - m_ActiveEdges = edge; - } else - { - TEdge* e = m_ActiveEdges; - while( e->nextInAEL && !E2InsertsBeforeE1(*e->nextInAEL , *edge) ) - e = e->nextInAEL; - edge->nextInAEL = e->nextInAEL; - if( e->nextInAEL ) e->nextInAEL->prevInAEL = edge; - edge->prevInAEL = e; - e->nextInAEL = edge; - } -} -//---------------------------------------------------------------------- - -void Clipper::DoEdge1(TEdge *edge1, TEdge *edge2, const IntPoint &pt) -{ - AddOutPt(edge1, pt); - SwapSides(*edge1, *edge2); - SwapPolyIndexes(*edge1, *edge2); -} -//---------------------------------------------------------------------- - -void Clipper::DoEdge2(TEdge *edge1, TEdge *edge2, const IntPoint &pt) -{ - AddOutPt(edge2, pt); - SwapSides(*edge1, *edge2); - SwapPolyIndexes(*edge1, *edge2); -} -//---------------------------------------------------------------------- - -void Clipper::DoBothEdges(TEdge *edge1, TEdge *edge2, const IntPoint &pt) -{ - AddOutPt(edge1, pt); - AddOutPt(edge2, pt); - SwapSides( *edge1 , *edge2 ); - SwapPolyIndexes( *edge1 , *edge2 ); -} -//---------------------------------------------------------------------- - -void Clipper::CheckHoleLinkages1(OutRec *outRec1, OutRec *outRec2) -{ - //when a polygon is split into 2 polygons, make sure any holes the original - //polygon contained link to the correct polygon ... - for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) - { - OutRec *orec = m_PolyOuts[i]; - if (orec->isHole && orec->bottomPt && orec->FirstLeft == outRec1 && - !PointInPolygon(orec->bottomPt->pt, outRec1->pts, m_UseFullRange)) - orec->FirstLeft = outRec2; - } -} -//---------------------------------------------------------------------- - -void Clipper::CheckHoleLinkages2(OutRec *outRec1, OutRec *outRec2) -{ - //if a hole is owned by outRec2 then make it owned by outRec1 ... - for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) - if (m_PolyOuts[i]->isHole && m_PolyOuts[i]->bottomPt && - m_PolyOuts[i]->FirstLeft == outRec2) - m_PolyOuts[i]->FirstLeft = outRec1; -} -//---------------------------------------------------------------------- - -void Clipper::JoinCommonEdges(bool fixHoleLinkages) -{ - for (JoinList::size_type i = 0; i < m_Joins.size(); i++) - { - JoinRec* j = m_Joins[i]; - OutRec *outRec1 = m_PolyOuts[j->poly1Idx]; - OutPt *pp1a = outRec1->pts; - OutRec *outRec2 = m_PolyOuts[j->poly2Idx]; - OutPt *pp2a = outRec2->pts; - IntPoint pt1 = j->pt2a, pt2 = j->pt2b; - IntPoint pt3 = j->pt1a, pt4 = j->pt1b; - if (!FindSegment(pp1a, pt1, pt2)) continue; - if (j->poly1Idx == j->poly2Idx) - { - //we're searching the same polygon for overlapping segments so - //segment 2 mustn't be the same as segment 1 ... - pp2a = pp1a->next; - if (!FindSegment(pp2a, pt3, pt4) || (pp2a == pp1a)) continue; - } - else if (!FindSegment(pp2a, pt3, pt4)) continue; - - if (!GetOverlapSegment(pt1, pt2, pt3, pt4, pt1, pt2)) continue; - - OutPt *p1, *p2, *p3, *p4; - OutPt *prev = pp1a->prev; - //get p1 & p2 polypts - the overlap start & endpoints on poly1 - if (PointsEqual(pp1a->pt, pt1)) p1 = pp1a; - else if (PointsEqual(prev->pt, pt1)) p1 = prev; - else p1 = InsertPolyPtBetween(pp1a, prev, pt1); - - if (PointsEqual(pp1a->pt, pt2)) p2 = pp1a; - else if (PointsEqual(prev->pt, pt2)) p2 = prev; - else if ((p1 == pp1a) || (p1 == prev)) - p2 = InsertPolyPtBetween(pp1a, prev, pt2); - else if (Pt3IsBetweenPt1AndPt2(pp1a->pt, p1->pt, pt2)) - p2 = InsertPolyPtBetween(pp1a, p1, pt2); else - p2 = InsertPolyPtBetween(p1, prev, pt2); - - //get p3 & p4 polypts - the overlap start & endpoints on poly2 - prev = pp2a->prev; - if (PointsEqual(pp2a->pt, pt1)) p3 = pp2a; - else if (PointsEqual(prev->pt, pt1)) p3 = prev; - else p3 = InsertPolyPtBetween(pp2a, prev, pt1); - - if (PointsEqual(pp2a->pt, pt2)) p4 = pp2a; - else if (PointsEqual(prev->pt, pt2)) p4 = prev; - else if ((p3 == pp2a) || (p3 == prev)) - p4 = InsertPolyPtBetween(pp2a, prev, pt2); - else if (Pt3IsBetweenPt1AndPt2(pp2a->pt, p3->pt, pt2)) - p4 = InsertPolyPtBetween(pp2a, p3, pt2); else - p4 = InsertPolyPtBetween(p3, prev, pt2); - - //p1.pt == p3.pt and p2.pt == p4.pt so join p1 to p3 and p2 to p4 ... - if (p1->next == p2 && p3->prev == p4) - { - p1->next = p3; - p3->prev = p1; - p2->prev = p4; - p4->next = p2; - } - else if (p1->prev == p2 && p3->next == p4) - { - p1->prev = p3; - p3->next = p1; - p2->next = p4; - p4->prev = p2; - } - else - continue; //an orientation is probably wrong - - if (j->poly2Idx == j->poly1Idx) - { - //instead of joining two polygons, we've just created a new one by - //splitting one polygon into two. - outRec1->pts = GetBottomPt(p1); - outRec1->bottomPt = outRec1->pts; - outRec1->bottomPt->idx = outRec1->idx; - outRec2 = CreateOutRec(); - m_PolyOuts.push_back(outRec2); - outRec2->idx = (int)m_PolyOuts.size()-1; - j->poly2Idx = outRec2->idx; - outRec2->pts = GetBottomPt(p2); - outRec2->bottomPt = outRec2->pts; - outRec2->bottomPt->idx = outRec2->idx; - - if (PointInPolygon(outRec2->pts->pt, outRec1->pts, m_UseFullRange)) - { - //outRec2 is contained by outRec1 ... - outRec2->isHole = !outRec1->isHole; - outRec2->FirstLeft = outRec1; - if (outRec2->isHole == - (m_ReverseOutput ^ Orientation(outRec2, m_UseFullRange))) - ReversePolyPtLinks(*outRec2->pts); - } else if (PointInPolygon(outRec1->pts->pt, outRec2->pts, m_UseFullRange)) - { - //outRec1 is contained by outRec2 ... - outRec2->isHole = outRec1->isHole; - outRec1->isHole = !outRec2->isHole; - outRec2->FirstLeft = outRec1->FirstLeft; - outRec1->FirstLeft = outRec2; - if (outRec1->isHole == - (m_ReverseOutput ^ Orientation(outRec1, m_UseFullRange))) - ReversePolyPtLinks(*outRec1->pts); - //make sure any contained holes now link to the correct polygon ... - if (fixHoleLinkages) CheckHoleLinkages1(outRec1, outRec2); - } else - { - outRec2->isHole = outRec1->isHole; - outRec2->FirstLeft = outRec1->FirstLeft; - //make sure any contained holes now link to the correct polygon ... - if (fixHoleLinkages) CheckHoleLinkages1(outRec1, outRec2); - } - - //now fixup any subsequent joins that match this polygon - for (JoinList::size_type k = i+1; k < m_Joins.size(); k++) - { - JoinRec* j2 = m_Joins[k]; - if (j2->poly1Idx == j->poly1Idx && PointIsVertex(j2->pt1a, p2)) - j2->poly1Idx = j->poly2Idx; - if (j2->poly2Idx == j->poly1Idx && PointIsVertex(j2->pt2a, p2)) - j2->poly2Idx = j->poly2Idx; - } - - //now cleanup redundant edges too ... - FixupOutPolygon(*outRec1); - FixupOutPolygon(*outRec2); - - if (Orientation(outRec1, m_UseFullRange) != (Area(*outRec1, m_UseFullRange) > 0)) - DisposeBottomPt(*outRec1); - if (Orientation(outRec2, m_UseFullRange) != (Area(*outRec2, m_UseFullRange) > 0)) - DisposeBottomPt(*outRec2); - - } else - { - //joined 2 polygons together ... - - //make sure any holes contained by outRec2 now link to outRec1 ... - if (fixHoleLinkages) CheckHoleLinkages2(outRec1, outRec2); - - //now cleanup redundant edges too ... - FixupOutPolygon(*outRec1); - - if (outRec1->pts) - { - outRec1->isHole = !Orientation(outRec1, m_UseFullRange); - if (outRec1->isHole && !outRec1->FirstLeft) - outRec1->FirstLeft = outRec2->FirstLeft; - } - - //delete the obsolete pointer ... - int OKIdx = outRec1->idx; - int ObsoleteIdx = outRec2->idx; - outRec2->pts = 0; - outRec2->bottomPt = 0; - outRec2->AppendLink = outRec1; - - //now fixup any subsequent Joins that match this polygon - for (JoinList::size_type k = i+1; k < m_Joins.size(); k++) - { - JoinRec* j2 = m_Joins[k]; - if (j2->poly1Idx == ObsoleteIdx) j2->poly1Idx = OKIdx; - if (j2->poly2Idx == ObsoleteIdx) j2->poly2Idx = OKIdx; - } - } - } -} -//------------------------------------------------------------------------------ - -void ReversePolygon(Polygon& p) -{ - std::reverse(p.begin(), p.end()); -} -//------------------------------------------------------------------------------ - -void ReversePolygons(Polygons& p) -{ - for (Polygons::size_type i = 0; i < p.size(); ++i) - ReversePolygon(p[i]); -} - -//------------------------------------------------------------------------------ -// OffsetPolygon functions ... -//------------------------------------------------------------------------------ - -struct DoublePoint -{ - double X; - double Y; - DoublePoint(double x = 0, double y = 0) : X(x), Y(y) {} -}; -//------------------------------------------------------------------------------ - -Polygon BuildArc(const IntPoint &pt, - const double a1, const double a2, const double r) -{ - long64 steps = std::max(6, int(std::sqrt(std::fabs(r)) * std::fabs(a2 - a1))); - if (steps > 0x100000) steps = 0x100000; - int n = (unsigned)steps; - Polygon result(n); - double da = (a2 - a1) / (n -1); - double a = a1; - for (int i = 0; i < n; ++i) - { - result[i].X = pt.X + Round(std::cos(a)*r); - result[i].Y = pt.Y + Round(std::sin(a)*r); - a += da; - } - return result; -} -//------------------------------------------------------------------------------ - -DoublePoint GetUnitNormal( const IntPoint &pt1, const IntPoint &pt2) -{ - if(pt2.X == pt1.X && pt2.Y == pt1.Y) - return DoublePoint(0, 0); - - double dx = (double)(pt2.X - pt1.X); - double dy = (double)(pt2.Y - pt1.Y); - double f = 1 *1.0/ std::sqrt( dx*dx + dy*dy ); - dx *= f; - dy *= f; - return DoublePoint(dy, -dx); -} - -//------------------------------------------------------------------------------ -//------------------------------------------------------------------------------ - -class PolyOffsetBuilder -{ -private: - Polygons m_p; - Polygon* m_curr_poly; - std::vector normals; - double m_delta, m_RMin, m_R; - size_t m_i, m_j, m_k; - static const int buffLength = 128; - JoinType m_jointype; - -public: - -PolyOffsetBuilder(const Polygons& in_polys, Polygons& out_polys, - double delta, JoinType jointype, double MiterLimit) -{ - //nb precondition - out_polys != ptsin_polys - if (NEAR_ZERO(delta)) - { - out_polys = in_polys; - return; - } - - this->m_p = in_polys; - this->m_delta = delta; - this->m_jointype = jointype; - if (MiterLimit <= 1) MiterLimit = 1; - m_RMin = 2/(MiterLimit*MiterLimit); - - double deltaSq = delta*delta; - out_polys.clear(); - out_polys.resize(in_polys.size()); - for (m_i = 0; m_i < in_polys.size(); m_i++) - { - m_curr_poly = &out_polys[m_i]; - size_t len = in_polys[m_i].size(); - if (len > 1 && m_p[m_i][0].X == m_p[m_i][len - 1].X && - m_p[m_i][0].Y == m_p[m_i][len-1].Y) len--; - - //when 'shrinking' polygons - to minimize artefacts - //strip those polygons that have an area < pi * delta^2 ... - double a1 = Area(in_polys[m_i]); - if (delta < 0) { if (a1 > 0 && a1 < deltaSq *pi) len = 0; } - else if (a1 < 0 && -a1 < deltaSq *pi) len = 0; //holes have neg. area - - if (len == 0 || (len < 3 && delta <= 0)) - continue; - else if (len == 1) - { - Polygon arc; - arc = BuildArc(in_polys[m_i][len-1], 0, 2 * pi, delta); - out_polys[m_i] = arc; - continue; - } - - //build normals ... - normals.clear(); - normals.resize(len); - normals[len-1] = GetUnitNormal(in_polys[m_i][len-1], in_polys[m_i][0]); - for (m_j = 0; m_j < len -1; ++m_j) - normals[m_j] = GetUnitNormal(in_polys[m_i][m_j], in_polys[m_i][m_j+1]); - - m_k = len -1; - for (m_j = 0; m_j < len; ++m_j) - { - switch (jointype) - { - case jtMiter: - { - m_R = 1 + (normals[m_j].X*normals[m_k].X + - normals[m_j].Y*normals[m_k].Y); - if (m_R >= m_RMin) DoMiter(); else DoSquare(MiterLimit); - break; - } - case jtSquare: DoSquare(); break; - case jtRound: DoRound(); break; - } - m_k = m_j; - } - } - - //finally, clean up untidy corners using Clipper ... - Clipper clpr; - clpr.AddPolygons(out_polys, ptSubject); - if (delta > 0) - { - if (!clpr.Execute(ctUnion, out_polys, pftPositive, pftPositive)) - out_polys.clear(); - } - else - { - IntRect r = clpr.GetBounds(); - Polygon outer(4); - outer[0] = IntPoint(r.left - 10, r.bottom + 10); - outer[1] = IntPoint(r.right + 10, r.bottom + 10); - outer[2] = IntPoint(r.right + 10, r.top - 10); - outer[3] = IntPoint(r.left - 10, r.top - 10); - - clpr.AddPolygon(outer, ptSubject); - if (clpr.Execute(ctUnion, out_polys, pftNegative, pftNegative)) - { - out_polys.erase(out_polys.begin()); - ReversePolygons(out_polys); - - } else - out_polys.clear(); - } -} -//------------------------------------------------------------------------------ - -private: - -void AddPoint(const IntPoint& pt) -{ - Polygon::size_type len = m_curr_poly->size(); - if (len == m_curr_poly->capacity()) - m_curr_poly->reserve(len + buffLength); - m_curr_poly->push_back(pt); -} -//------------------------------------------------------------------------------ - -void DoSquare(double mul = 1.0) -{ - IntPoint pt1 = IntPoint((long64)Round(m_p[m_i][m_j].X + normals[m_k].X * m_delta), - (long64)Round(m_p[m_i][m_j].Y + normals[m_k].Y * m_delta)); - IntPoint pt2 = IntPoint((long64)Round(m_p[m_i][m_j].X + normals[m_j].X * m_delta), - (long64)Round(m_p[m_i][m_j].Y + normals[m_j].Y * m_delta)); - if ((normals[m_k].X * normals[m_j].Y - normals[m_j].X * normals[m_k].Y) * m_delta >= 0) - { - double a1 = std::atan2(normals[m_k].Y, normals[m_k].X); - double a2 = std::atan2(-normals[m_j].Y, -normals[m_j].X); - a1 = std::fabs(a2 - a1); - if (a1 > pi) a1 = pi * 2 - a1; - double dx = std::tan((pi - a1)/4) * std::fabs(m_delta * mul); - pt1 = IntPoint((long64)(pt1.X -normals[m_k].Y * dx), - (long64)(pt1.Y + normals[m_k].X * dx)); - AddPoint(pt1); - pt2 = IntPoint((long64)(pt2.X + normals[m_j].Y * dx), - (long64)(pt2.Y -normals[m_j].X * dx)); - AddPoint(pt2); - } - else - { - AddPoint(pt1); - AddPoint(m_p[m_i][m_j]); - AddPoint(pt2); - } -} -//------------------------------------------------------------------------------ - -void DoMiter() -{ - if ((normals[m_k].X * normals[m_j].Y - normals[m_j].X * normals[m_k].Y) * m_delta >= 0) - { - double q = m_delta / m_R; - AddPoint(IntPoint((long64)Round(m_p[m_i][m_j].X + - (normals[m_k].X + normals[m_j].X) * q), - (long64)Round(m_p[m_i][m_j].Y + (normals[m_k].Y + normals[m_j].Y) * q))); - } - else - { - IntPoint pt1 = IntPoint((long64)Round(m_p[m_i][m_j].X + normals[m_k].X * - m_delta), (long64)Round(m_p[m_i][m_j].Y + normals[m_k].Y * m_delta)); - IntPoint pt2 = IntPoint((long64)Round(m_p[m_i][m_j].X + normals[m_j].X * - m_delta), (long64)Round(m_p[m_i][m_j].Y + normals[m_j].Y * m_delta)); - AddPoint(pt1); - AddPoint(m_p[m_i][m_j]); - AddPoint(pt2); - } -} -//------------------------------------------------------------------------------ - -void DoRound() -{ - IntPoint pt1 = IntPoint((long64)Round(m_p[m_i][m_j].X + normals[m_k].X * m_delta), - (long64)Round(m_p[m_i][m_j].Y + normals[m_k].Y * m_delta)); - IntPoint pt2 = IntPoint((long64)Round(m_p[m_i][m_j].X + normals[m_j].X * m_delta), - (long64)Round(m_p[m_i][m_j].Y + normals[m_j].Y * m_delta)); - AddPoint(pt1); - //round off reflex angles (ie > 180 deg) unless almost flat (ie < ~10deg). - if ((normals[m_k].X*normals[m_j].Y - normals[m_j].X*normals[m_k].Y) * m_delta >= 0) - { - if (normals[m_j].X * normals[m_k].X + normals[m_j].Y * normals[m_k].Y < 0.985) - { - double a1 = std::atan2(normals[m_k].Y, normals[m_k].X); - double a2 = std::atan2(normals[m_j].Y, normals[m_j].X); - if (m_delta > 0 && a2 < a1) a2 += pi *2; - else if (m_delta < 0 && a2 > a1) a2 -= pi *2; - Polygon arc = BuildArc(m_p[m_i][m_j], a1, a2, m_delta); - for (Polygon::size_type m = 0; m < arc.size(); m++) - AddPoint(arc[m]); - } - } - else - AddPoint(m_p[m_i][m_j]); - AddPoint(pt2); -} -//-------------------------------------------------------------------------- - -}; //end PolyOffsetBuilder - -//------------------------------------------------------------------------------ -//------------------------------------------------------------------------------ - -void OffsetPolygons(const Polygons &in_polys, Polygons &out_polys, - double delta, JoinType jointype, double MiterLimit) -{ - if (&out_polys == &in_polys) - { - Polygons poly2(in_polys); - PolyOffsetBuilder(poly2, out_polys, delta, jointype, MiterLimit); - } - else PolyOffsetBuilder(in_polys, out_polys, delta, jointype, MiterLimit); -} -//------------------------------------------------------------------------------ - -void SimplifyPolygon(const Polygon &in_poly, Polygons &out_polys, PolyFillType fillType) -{ - Clipper c; - c.AddPolygon(in_poly, ptSubject); - c.Execute(ctUnion, out_polys, fillType, fillType); -} -//------------------------------------------------------------------------------ - -void SimplifyPolygons(const Polygons &in_polys, Polygons &out_polys, PolyFillType fillType) -{ - Clipper c; - c.AddPolygons(in_polys, ptSubject); - c.Execute(ctUnion, out_polys, fillType, fillType); -} -//------------------------------------------------------------------------------ - -void SimplifyPolygons(Polygons &polys, PolyFillType fillType) -{ - SimplifyPolygons(polys, polys, fillType); -} -//------------------------------------------------------------------------------ - -std::ostream& operator <<(std::ostream &s, IntPoint& p) -{ - s << p.X << ' ' << p.Y << "\n"; - return s; -} -//------------------------------------------------------------------------------ - -std::ostream& operator <<(std::ostream &s, Polygon &p) -{ - for (Polygon::size_type i = 0; i < p.size(); i++) - s << p[i]; - s << "\n"; - return s; -} -//------------------------------------------------------------------------------ - -std::ostream& operator <<(std::ostream &s, Polygons &p) -{ - for (Polygons::size_type i = 0; i < p.size(); i++) - s << p[i]; - s << "\n"; - return s; -} -//------------------------------------------------------------------------------ - -} //ClipperLib namespace +/******************************************************************************* +* * +* Author : Angus Johnson * +* Version : 4.8.8 * +* Date : 30 August 2012 * +* Website : http://www.angusj.com * +* Copyright : Angus Johnson 2010-2012 * +* * +* License: * +* Use, modification & distribution is subject to Boost Software License Ver 1. * +* http://www.boost.org/LICENSE_1_0.txt * +* * +* Attributions: * +* The code in this library is an extension of Bala Vatti's clipping algorithm: * +* "A generic solution to polygon clipping" * +* Communications of the ACM, Vol 35, Issue 7 (July 1992) pp 56-63. * +* http://portal.acm.org/citation.cfm?id=129906 * +* * +* Computer graphics and geometric modeling: implementation and algorithms * +* By Max K. Agoston * +* Springer; 1 edition (January 4, 2005) * +* http://books.google.com/books?q=vatti+clipping+agoston * +* * +* See also: * +* "Polygon Offsetting by Computing Winding Numbers" * +* Paper no. DETC2005-85513 pp. 565-575 * +* ASME 2005 International Design Engineering Technical Conferences * +* and Computers and Information in Engineering Conference (IDETC/CIE2005) * +* September 24–28, 2005 , Long Beach, California, USA * +* http://www.me.berkeley.edu/~mcmains/pubs/DAC05OffsetPolygon.pdf * +* * +*******************************************************************************/ + +/******************************************************************************* +* * +* This is a translation of the Delphi Clipper library and the naming style * +* used has retained a Delphi flavour. * +* * +*******************************************************************************/ + +#include "clipper.hpp" +#include +#include +#include +#include +#include +#include +#include + +namespace ClipperLib { + +static long64 const loRange = 0x3FFFFFFF; +static long64 const hiRange = 0x3FFFFFFFFFFFFFFFLL; +static double const pi = 3.141592653589793238; +enum Direction { dRightToLeft, dLeftToRight }; + +#define HORIZONTAL (-1.0E+40) +#define TOLERANCE (1.0e-20) +#define NEAR_ZERO(val) (((val) > -TOLERANCE) && ((val) < TOLERANCE)) +#define NEAR_EQUAL(a, b) NEAR_ZERO((a) - (b)) + +inline long64 Abs(long64 val) +{ + return val < 0 ? -val : val; +} +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// Int128 class (enables safe math on signed 64bit integers) +// eg Int128 val1((long64)9223372036854775807); //ie 2^63 -1 +// Int128 val2((long64)9223372036854775807); +// Int128 val3 = val1 * val2; +// val3.AsString => "85070591730234615847396907784232501249" (8.5e+37) +//------------------------------------------------------------------------------ + +class Int128 +{ + public: + + Int128(long64 _lo = 0) + { + lo = _lo; + if (lo < 0) hi = -1; else hi = 0; + } + + Int128(const Int128 &val): hi(val.hi), lo(val.lo){} + + long64 operator = (const long64 &val) + { + lo = val; + if (lo < 0) hi = -1; else hi = 0; + return val; + } + + bool operator == (const Int128 &val) const + {return (hi == val.hi && lo == val.lo);} + + bool operator != (const Int128 &val) const + { return !(*this == val);} + + bool operator > (const Int128 &val) const + { + if (hi != val.hi) + return hi > val.hi; + else + return lo > val.lo; + } + + bool operator < (const Int128 &val) const + { + if (hi != val.hi) + return hi < val.hi; + else + return lo < val.lo; + } + + bool operator >= (const Int128 &val) const + { return !(*this < val);} + + bool operator <= (const Int128 &val) const + { return !(*this > val);} + + Int128& operator += (const Int128 &rhs) + { + hi += rhs.hi; + lo += rhs.lo; + if (ulong64(lo) < ulong64(rhs.lo)) hi++; + return *this; + } + + Int128 operator + (const Int128 &rhs) const + { + Int128 result(*this); + result+= rhs; + return result; + } + + Int128& operator -= (const Int128 &rhs) + { + Int128 tmp(rhs); + Negate(tmp); + *this += tmp; + return *this; + } + + //Int128 operator -() const + //{ + // Int128 result(*this); + // if (result.lo == 0) { + // if (result.hi != 0) result.hi = -1; + // } + // else { + // result.lo = -result.lo; + // result.hi = ~result.hi; + // } + // return result; + //} + + Int128 operator - (const Int128 &rhs) const + { + Int128 result(*this); + result -= rhs; + return result; + } + + Int128 operator * (const Int128 &rhs) const + { + if ( !(hi == 0 || hi == -1) || !(rhs.hi == 0 || rhs.hi == -1)) + throw "Int128 operator*: overflow error"; + bool negate = (hi < 0) != (rhs.hi < 0); + + Int128 tmp(*this); + if (tmp.hi < 0) Negate(tmp); + ulong64 int1Hi = ulong64(tmp.lo) >> 32; + ulong64 int1Lo = ulong64(tmp.lo & 0xFFFFFFFF); + + tmp = rhs; + if (tmp.hi < 0) Negate(tmp); + ulong64 int2Hi = ulong64(tmp.lo) >> 32; + ulong64 int2Lo = ulong64(tmp.lo & 0xFFFFFFFF); + + //nb: see comments in clipper.pas + ulong64 a = int1Hi * int2Hi; + ulong64 b = int1Lo * int2Lo; + ulong64 c = int1Hi * int2Lo + int1Lo * int2Hi; + + tmp.hi = long64(a + (c >> 32)); + tmp.lo = long64(c << 32); + tmp.lo += long64(b); + if (ulong64(tmp.lo) < b) tmp.hi++; + if (negate) Negate(tmp); + return tmp; + } + + Int128 operator/ (const Int128 &rhs) const + { + if (rhs.lo == 0 && rhs.hi == 0) + throw "Int128 operator/: divide by zero"; + bool negate = (rhs.hi < 0) != (hi < 0); + Int128 result(*this), denom(rhs); + if (result.hi < 0) Negate(result); + if (denom.hi < 0) Negate(denom); + if (denom > result) return Int128(0); //result is only a fraction of 1 + Negate(denom); + + Int128 p(0); + for (int i = 0; i < 128; ++i) + { + p.hi = p.hi << 1; + if (p.lo < 0) p.hi++; + p.lo = long64(p.lo) << 1; + if (result.hi < 0) p.lo++; + result.hi = result.hi << 1; + if (result.lo < 0) result.hi++; + result.lo = long64(result.lo) << 1; + Int128 p2(p); + p += denom; + if (p.hi < 0) p = p2; + else result.lo++; + } + if (negate) Negate(result); + return result; + } + + double AsDouble() const + { + const double shift64 = 18446744073709551616.0; //2^64 + const double bit64 = 9223372036854775808.0; + if (hi < 0) + { + Int128 tmp(*this); + Negate(tmp); + if (tmp.lo < 0) + return (double)tmp.lo - bit64 - tmp.hi * shift64; + else + return -(double)tmp.lo - tmp.hi * shift64; + } + else if (lo < 0) + return -(double)lo + bit64 + hi * shift64; + else + return (double)lo + (double)hi * shift64; + } + + //for bug testing ... + //std::string AsString() const + //{ + // std::string result; + // unsigned char r = 0; + // Int128 tmp(0), val(*this); + // if (hi < 0) Negate(val); + // result.resize(50); + // std::string::size_type i = result.size() -1; + // while (val.hi != 0 || val.lo != 0) + // { + // Div10(val, tmp, r); + // result[i--] = char('0' + r); + // val = tmp; + // } + // if (hi < 0) result[i--] = '-'; + // result.erase(0,i+1); + // if (result.size() == 0) result = "0"; + // return result; + //} + +private: + long64 hi; + long64 lo; + + static void Negate(Int128 &val) + { + if (val.lo == 0) { + if (val.hi != 0) val.hi = -val.hi;; + } + else { + val.lo = -val.lo; + val.hi = ~val.hi; + } + } + + //debugging only ... + //void Div10(const Int128 val, Int128& result, unsigned char & remainder) const + //{ + // remainder = 0; + // result = 0; + // for (int i = 63; i >= 0; --i) + // { + // if ((val.hi & ((long64)1 << i)) != 0) + // remainder = char((remainder * 2) + 1); else + // remainder *= char(2); + // if (remainder >= 10) + // { + // result.hi += ((long64)1 << i); + // remainder -= char(10); + // } + // } + // for (int i = 63; i >= 0; --i) + // { + // if ((val.lo & ((long64)1 << i)) != 0) + // remainder = char((remainder * 2) + 1); else + // remainder *= char(2); + // if (remainder >= 10) + // { + // result.lo += ((long64)1 << i); + // remainder -= char(10); + // } + // } + //} +}; + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ + +bool FullRangeNeeded(const Polygon &pts) +{ + bool result = false; + for (Polygon::size_type i = 0; i < pts.size(); ++i) + { + if (Abs(pts[i].X) > hiRange || Abs(pts[i].Y) > hiRange) + throw "Coordinate exceeds range bounds."; + else if (Abs(pts[i].X) > loRange || Abs(pts[i].Y) > loRange) + result = true; + } + return result; +} +//------------------------------------------------------------------------------ + +bool Orientation(const Polygon &poly) +{ + int highI = (int)poly.size() -1; + if (highI < 2) return false; + + int j = 0, jplus, jminus; + for (int i = 0; i <= highI; ++i) + { + if (poly[i].Y < poly[j].Y) continue; + if ((poly[i].Y > poly[j].Y || poly[i].X < poly[j].X)) j = i; + }; + if (j == highI) jplus = 0; + else jplus = j +1; + if (j == 0) jminus = highI; + else jminus = j -1; + + IntPoint vec1, vec2; + //get cross product of vectors of the edges adjacent to highest point ... + vec1.X = poly[j].X - poly[jminus].X; + vec1.Y = poly[j].Y - poly[jminus].Y; + vec2.X = poly[jplus].X - poly[j].X; + vec2.Y = poly[jplus].Y - poly[j].Y; + + if (Abs(vec1.X) > loRange || Abs(vec1.Y) > loRange || + Abs(vec2.X) > loRange || Abs(vec2.Y) > loRange) + { + if (Abs(vec1.X) > hiRange || Abs(vec1.Y) > hiRange || + Abs(vec2.X) > hiRange || Abs(vec2.Y) > hiRange) + throw "Coordinate exceeds range bounds."; + Int128 cross = Int128(vec1.X) * Int128(vec2.Y) - + Int128(vec2.X) * Int128(vec1.Y); + return cross >= 0; + } + else + return (vec1.X * vec2.Y - vec2.X * vec1.Y) >= 0; +} +//------------------------------------------------------------------------------ + +inline bool PointsEqual( const IntPoint &pt1, const IntPoint &pt2) +{ + return ( pt1.X == pt2.X && pt1.Y == pt2.Y ); +} +//------------------------------------------------------------------------------ + +bool Orientation(OutRec *outRec, bool UseFullInt64Range) +{ + //first make sure bottomPt is correctly assigned ... + OutPt *opBottom = outRec->pts, *op = outRec->pts->next; + while (op != outRec->pts) + { + if (op->pt.Y >= opBottom->pt.Y) + { + if (op->pt.Y > opBottom->pt.Y || op->pt.X < opBottom->pt.X) + opBottom = op; + } + op = op->next; + } + outRec->bottomPt = opBottom; + opBottom->idx = outRec->idx; + + op = opBottom; + //find vertices either side of bottomPt (skipping duplicate points) .... + OutPt *opPrev = op->prev; + OutPt *opNext = op->next; + while (op != opPrev && PointsEqual(op->pt, opPrev->pt)) + opPrev = opPrev->prev; + while (op != opNext && PointsEqual(op->pt, opNext->pt)) + opNext = opNext->next; + + IntPoint ip1, ip2; + ip1.X = op->pt.X - opPrev->pt.X; + ip1.Y = op->pt.Y - opPrev->pt.Y; + ip2.X = opNext->pt.X - op->pt.X; + ip2.Y = opNext->pt.Y - op->pt.Y; + + if (UseFullInt64Range) + return Int128(ip1.X) * Int128(ip2.Y) - Int128(ip2.X) * Int128(ip1.Y) >= 0; + else + return (ip1.X * ip2.Y - ip2.X * ip1.Y) >= 0; +} +//------------------------------------------------------------------------------ + +double Area(const Polygon &poly) +{ + int highI = (int)poly.size() -1; + if (highI < 2) return 0; + + if (FullRangeNeeded(poly)) { + Int128 a; + a = (Int128(poly[highI].X) * Int128(poly[0].Y)) - + Int128(poly[0].X) * Int128(poly[highI].Y); + for (int i = 0; i < highI; ++i) + a += Int128(poly[i].X) * Int128(poly[i+1].Y) - + Int128(poly[i+1].X) * Int128(poly[i].Y); + return a.AsDouble() / 2; + } + else + { + double a; + a = (double)poly[highI].X * poly[0].Y - (double)poly[0].X * poly[highI].Y; + for (int i = 0; i < highI; ++i) + a += (double)poly[i].X * poly[i+1].Y - (double)poly[i+1].X * poly[i].Y; + return a/2; + } +} +//------------------------------------------------------------------------------ + +double Area(const OutRec &outRec, bool UseFullInt64Range) +{ + OutPt *op = outRec.pts; + if (UseFullInt64Range) { + Int128 a(0); + do { + a += (Int128(op->prev->pt.X) * Int128(op->pt.Y)) - + Int128(op->pt.X) * Int128(op->prev->pt.Y); + op = op->next; + } while (op != outRec.pts); + return a.AsDouble() / 2; + } + else + { + double a = 0; + do { + a += (op->prev->pt.X * op->pt.Y) - (op->pt.X * op->prev->pt.Y); + op = op->next; + } while (op != outRec.pts); + return a/2; + } +} +//------------------------------------------------------------------------------ + +bool PointIsVertex(const IntPoint &pt, OutPt *pp) +{ + OutPt *pp2 = pp; + do + { + if (PointsEqual(pp2->pt, pt)) return true; + pp2 = pp2->next; + } + while (pp2 != pp); + return false; +} +//------------------------------------------------------------------------------ + +bool PointInPolygon(const IntPoint &pt, OutPt *pp, bool UseFullInt64Range) +{ + OutPt *pp2 = pp; + bool result = false; + if (UseFullInt64Range) { + do + { + if ((((pp2->pt.Y <= pt.Y) && (pt.Y < pp2->prev->pt.Y)) || + ((pp2->prev->pt.Y <= pt.Y) && (pt.Y < pp2->pt.Y))) && + Int128(pt.X - pp2->pt.X) < (Int128(pp2->prev->pt.X - pp2->pt.X) * + Int128(pt.Y - pp2->pt.Y)) / Int128(pp2->prev->pt.Y - pp2->pt.Y)) + result = !result; + pp2 = pp2->next; + } + while (pp2 != pp); + } + else + { + do + { + if ((((pp2->pt.Y <= pt.Y) && (pt.Y < pp2->prev->pt.Y)) || + ((pp2->prev->pt.Y <= pt.Y) && (pt.Y < pp2->pt.Y))) && + (pt.X < (pp2->prev->pt.X - pp2->pt.X) * (pt.Y - pp2->pt.Y) / + (pp2->prev->pt.Y - pp2->pt.Y) + pp2->pt.X )) result = !result; + pp2 = pp2->next; + } + while (pp2 != pp); + } + return result; +} +//------------------------------------------------------------------------------ + +bool SlopesEqual(TEdge &e1, TEdge &e2, bool UseFullInt64Range) +{ + if (UseFullInt64Range) + return Int128(e1.ytop - e1.ybot) * Int128(e2.xtop - e2.xbot) == + Int128(e1.xtop - e1.xbot) * Int128(e2.ytop - e2.ybot); + else return (e1.ytop - e1.ybot)*(e2.xtop - e2.xbot) == + (e1.xtop - e1.xbot)*(e2.ytop - e2.ybot); +} +//------------------------------------------------------------------------------ + +bool SlopesEqual(const IntPoint pt1, const IntPoint pt2, + const IntPoint pt3, bool UseFullInt64Range) +{ + if (UseFullInt64Range) + return Int128(pt1.Y-pt2.Y) * Int128(pt2.X-pt3.X) == + Int128(pt1.X-pt2.X) * Int128(pt2.Y-pt3.Y); + else return (pt1.Y-pt2.Y)*(pt2.X-pt3.X) == (pt1.X-pt2.X)*(pt2.Y-pt3.Y); +} +//------------------------------------------------------------------------------ + +bool SlopesEqual(const IntPoint pt1, const IntPoint pt2, + const IntPoint pt3, const IntPoint pt4, bool UseFullInt64Range) +{ + if (UseFullInt64Range) + return Int128(pt1.Y-pt2.Y) * Int128(pt3.X-pt4.X) == + Int128(pt1.X-pt2.X) * Int128(pt3.Y-pt4.Y); + else return (pt1.Y-pt2.Y)*(pt3.X-pt4.X) == (pt1.X-pt2.X)*(pt3.Y-pt4.Y); +} +//------------------------------------------------------------------------------ + +double GetDx(const IntPoint pt1, const IntPoint pt2) +{ + return (pt1.Y == pt2.Y) ? + HORIZONTAL : (double)(pt2.X - pt1.X) / (double)(pt2.Y - pt1.Y); +} +//--------------------------------------------------------------------------- + +void SetDx(TEdge &e) +{ + if (e.ybot == e.ytop) e.dx = HORIZONTAL; + else e.dx = (double)(e.xtop - e.xbot) / (double)(e.ytop - e.ybot); +} +//--------------------------------------------------------------------------- + +void SwapSides(TEdge &edge1, TEdge &edge2) +{ + EdgeSide side = edge1.side; + edge1.side = edge2.side; + edge2.side = side; +} +//------------------------------------------------------------------------------ + +void SwapPolyIndexes(TEdge &edge1, TEdge &edge2) +{ + int outIdx = edge1.outIdx; + edge1.outIdx = edge2.outIdx; + edge2.outIdx = outIdx; +} +//------------------------------------------------------------------------------ + +inline long64 Round(double val) +{ + return (val < 0) ? + static_cast(val - 0.5) : static_cast(val + 0.5); +} +//------------------------------------------------------------------------------ + +long64 TopX(TEdge &edge, const long64 currentY) +{ + return ( currentY == edge.ytop ) ? + edge.xtop : edge.xbot + Round(edge.dx *(currentY - edge.ybot)); +} +//------------------------------------------------------------------------------ + +long64 TopX(const IntPoint pt1, const IntPoint pt2, const long64 currentY) +{ + //preconditions: pt1.Y <> pt2.Y and pt1.Y > pt2.Y + if (currentY >= pt1.Y) return pt1.X; + else if (currentY == pt2.Y) return pt2.X; + else if (pt1.X == pt2.X) return pt1.X; + else + { + double q = (double)(pt1.X-pt2.X)/(double)(pt1.Y-pt2.Y); + return Round(pt1.X + (currentY - pt1.Y) *q); + } +} +//------------------------------------------------------------------------------ + +bool IntersectPoint(TEdge &edge1, TEdge &edge2, + IntPoint &ip, bool UseFullInt64Range) +{ + double b1, b2; + if (SlopesEqual(edge1, edge2, UseFullInt64Range)) return false; + else if (NEAR_ZERO(edge1.dx)) + { + ip.X = edge1.xbot; + if (NEAR_EQUAL(edge2.dx, HORIZONTAL)) + { + ip.Y = edge2.ybot; + } else + { + b2 = edge2.ybot - (edge2.xbot/edge2.dx); + ip.Y = Round(ip.X/edge2.dx + b2); + } + } + else if (NEAR_ZERO(edge2.dx)) + { + ip.X = edge2.xbot; + if (NEAR_EQUAL(edge1.dx, HORIZONTAL)) + { + ip.Y = edge1.ybot; + } else + { + b1 = edge1.ybot - (edge1.xbot/edge1.dx); + ip.Y = Round(ip.X/edge1.dx + b1); + } + } else + { + b1 = edge1.xbot - edge1.ybot * edge1.dx; + b2 = edge2.xbot - edge2.ybot * edge2.dx; + b2 = (b2-b1)/(edge1.dx - edge2.dx); + ip.Y = Round(b2); + ip.X = Round(edge1.dx * b2 + b1); + } + + return + //can be *so close* to the top of one edge that the rounded Y equals one ytop ... + (ip.Y == edge1.ytop && ip.Y >= edge2.ytop && edge1.tmpX > edge2.tmpX) || + (ip.Y == edge2.ytop && ip.Y >= edge1.ytop && edge1.tmpX > edge2.tmpX) || + (ip.Y > edge1.ytop && ip.Y > edge2.ytop); +} +//------------------------------------------------------------------------------ + +void ReversePolyPtLinks(OutPt &pp) +{ + OutPt *pp1, *pp2; + pp1 = &pp; + do { + pp2 = pp1->next; + pp1->next = pp1->prev; + pp1->prev = pp2; + pp1 = pp2; + } while( pp1 != &pp ); +} +//------------------------------------------------------------------------------ + +void DisposeOutPts(OutPt*& pp) +{ + if (pp == 0) return; + pp->prev->next = 0; + while( pp ) + { + OutPt *tmpPp = pp; + pp = pp->next; + delete tmpPp ; + } +} +//------------------------------------------------------------------------------ + +void InitEdge(TEdge *e, TEdge *eNext, + TEdge *ePrev, const IntPoint &pt, PolyType polyType) +{ + std::memset( e, 0, sizeof( TEdge )); + + e->next = eNext; + e->prev = ePrev; + e->xcurr = pt.X; + e->ycurr = pt.Y; + if (e->ycurr >= e->next->ycurr) + { + e->xbot = e->xcurr; + e->ybot = e->ycurr; + e->xtop = e->next->xcurr; + e->ytop = e->next->ycurr; + e->windDelta = 1; + } else + { + e->xtop = e->xcurr; + e->ytop = e->ycurr; + e->xbot = e->next->xcurr; + e->ybot = e->next->ycurr; + e->windDelta = -1; + } + SetDx(*e); + e->polyType = polyType; + e->outIdx = -1; +} +//------------------------------------------------------------------------------ + +inline void SwapX(TEdge &e) +{ + //swap horizontal edges' top and bottom x's so they follow the natural + //progression of the bounds - ie so their xbots will align with the + //adjoining lower edge. [Helpful in the ProcessHorizontal() method.] + e.xcurr = e.xtop; + e.xtop = e.xbot; + e.xbot = e.xcurr; +} +//------------------------------------------------------------------------------ + +void SwapPoints(IntPoint &pt1, IntPoint &pt2) +{ + IntPoint tmp = pt1; + pt1 = pt2; + pt2 = tmp; +} +//------------------------------------------------------------------------------ + +bool GetOverlapSegment(IntPoint pt1a, IntPoint pt1b, IntPoint pt2a, + IntPoint pt2b, IntPoint &pt1, IntPoint &pt2) +{ + //precondition: segments are colinear. + if ( pt1a.Y == pt1b.Y || Abs((pt1a.X - pt1b.X)/(pt1a.Y - pt1b.Y)) > 1 ) + { + if (pt1a.X > pt1b.X) SwapPoints(pt1a, pt1b); + if (pt2a.X > pt2b.X) SwapPoints(pt2a, pt2b); + if (pt1a.X > pt2a.X) pt1 = pt1a; else pt1 = pt2a; + if (pt1b.X < pt2b.X) pt2 = pt1b; else pt2 = pt2b; + return pt1.X < pt2.X; + } else + { + if (pt1a.Y < pt1b.Y) SwapPoints(pt1a, pt1b); + if (pt2a.Y < pt2b.Y) SwapPoints(pt2a, pt2b); + if (pt1a.Y < pt2a.Y) pt1 = pt1a; else pt1 = pt2a; + if (pt1b.Y > pt2b.Y) pt2 = pt1b; else pt2 = pt2b; + return pt1.Y > pt2.Y; + } +} +//------------------------------------------------------------------------------ + +bool FirstIsBottomPt(const OutPt* btmPt1, const OutPt* btmPt2) +{ + OutPt *p = btmPt1->prev; + while (PointsEqual(p->pt, btmPt1->pt) && (p != btmPt1)) p = p->prev; + double dx1p = std::fabs(GetDx(btmPt1->pt, p->pt)); + p = btmPt1->next; + while (PointsEqual(p->pt, btmPt1->pt) && (p != btmPt1)) p = p->next; + double dx1n = std::fabs(GetDx(btmPt1->pt, p->pt)); + + p = btmPt2->prev; + while (PointsEqual(p->pt, btmPt2->pt) && (p != btmPt2)) p = p->prev; + double dx2p = std::fabs(GetDx(btmPt2->pt, p->pt)); + p = btmPt2->next; + while (PointsEqual(p->pt, btmPt2->pt) && (p != btmPt2)) p = p->next; + double dx2n = std::fabs(GetDx(btmPt2->pt, p->pt)); + return (dx1p >= dx2p && dx1p >= dx2n) || (dx1n >= dx2p && dx1n >= dx2n); +} +//------------------------------------------------------------------------------ + +OutPt* GetBottomPt(OutPt *pp) +{ + OutPt* dups = 0; + OutPt* p = pp->next; + while (p != pp) + { + if (p->pt.Y > pp->pt.Y) + { + pp = p; + dups = 0; + } + else if (p->pt.Y == pp->pt.Y && p->pt.X <= pp->pt.X) + { + if (p->pt.X < pp->pt.X) + { + dups = 0; + pp = p; + } else + { + if (p->next != pp && p->prev != pp) dups = p; + } + } + p = p->next; + } + if (dups) + { + //there appears to be at least 2 vertices at bottomPt so ... + while (dups != p) + { + if (!FirstIsBottomPt(p, dups)) pp = dups; + dups = dups->next; + while (!PointsEqual(dups->pt, pp->pt)) dups = dups->next; + } + } + return pp; +} +//------------------------------------------------------------------------------ + +bool FindSegment(OutPt* &pp, IntPoint &pt1, IntPoint &pt2) +{ + //outPt1 & outPt2 => the overlap segment (if the function returns true) + if (!pp) return false; + OutPt* pp2 = pp; + IntPoint pt1a = pt1, pt2a = pt2; + do + { + if (SlopesEqual(pt1a, pt2a, pp->pt, pp->prev->pt, true) && + SlopesEqual(pt1a, pt2a, pp->pt, true) && + GetOverlapSegment(pt1a, pt2a, pp->pt, pp->prev->pt, pt1, pt2)) + return true; + pp = pp->next; + } + while (pp != pp2); + return false; +} +//------------------------------------------------------------------------------ + +bool Pt3IsBetweenPt1AndPt2(const IntPoint pt1, + const IntPoint pt2, const IntPoint pt3) +{ + if (PointsEqual(pt1, pt3) || PointsEqual(pt2, pt3)) return true; + else if (pt1.X != pt2.X) return (pt1.X < pt3.X) == (pt3.X < pt2.X); + else return (pt1.Y < pt3.Y) == (pt3.Y < pt2.Y); +} +//------------------------------------------------------------------------------ + +OutPt* InsertPolyPtBetween(OutPt* p1, OutPt* p2, const IntPoint pt) +{ + if (p1 == p2) throw "JoinError"; + OutPt* result = new OutPt; + result->pt = pt; + if (p2 == p1->next) + { + p1->next = result; + p2->prev = result; + result->next = p2; + result->prev = p1; + } else + { + p2->next = result; + p1->prev = result; + result->next = p1; + result->prev = p2; + } + return result; +} + +//------------------------------------------------------------------------------ +// ClipperBase class methods ... +//------------------------------------------------------------------------------ + +ClipperBase::ClipperBase() //constructor +{ + m_MinimaList = 0; + m_CurrentLM = 0; + m_UseFullRange = true; +} +//------------------------------------------------------------------------------ + +ClipperBase::~ClipperBase() //destructor +{ + Clear(); +} +//------------------------------------------------------------------------------ + +bool ClipperBase::AddPolygon( const Polygon &pg, PolyType polyType) +{ + int len = (int)pg.size(); + if (len < 3) return false; + Polygon p(len); + p[0] = pg[0]; + int j = 0; + + long64 maxVal; + if (m_UseFullRange) maxVal = hiRange; else maxVal = loRange; + + for (int i = 0; i < len; ++i) + { + if (Abs(pg[i].X) > maxVal || Abs(pg[i].Y) > maxVal) + { + if (Abs(pg[i].X) > hiRange || Abs(pg[i].Y) > hiRange) + throw "Coordinate exceeds range bounds"; + maxVal = hiRange; + m_UseFullRange = true; + } + + if (i == 0 || PointsEqual(p[j], pg[i])) continue; + else if (j > 0 && SlopesEqual(p[j-1], p[j], pg[i], m_UseFullRange)) + { + if (PointsEqual(p[j-1], pg[i])) j--; + } else j++; + p[j] = pg[i]; + } + if (j < 2) return false; + + len = j+1; + while (len > 2) + { + //nb: test for point equality before testing slopes ... + if (PointsEqual(p[j], p[0])) j--; + else if (PointsEqual(p[0], p[1]) || + SlopesEqual(p[j], p[0], p[1], m_UseFullRange)) + p[0] = p[j--]; + else if (SlopesEqual(p[j-1], p[j], p[0], m_UseFullRange)) j--; + else if (SlopesEqual(p[0], p[1], p[2], m_UseFullRange)) + { + for (int i = 2; i <= j; ++i) p[i-1] = p[i]; + j--; + } + else break; + len--; + } + if (len < 3) return false; + + //create a new edge array ... + TEdge *edges = new TEdge [len]; + m_edges.push_back(edges); + + //convert vertices to a double-linked-list of edges and initialize ... + edges[0].xcurr = p[0].X; + edges[0].ycurr = p[0].Y; + InitEdge(&edges[len-1], &edges[0], &edges[len-2], p[len-1], polyType); + for (int i = len-2; i > 0; --i) + InitEdge(&edges[i], &edges[i+1], &edges[i-1], p[i], polyType); + InitEdge(&edges[0], &edges[1], &edges[len-1], p[0], polyType); + + //reset xcurr & ycurr and find 'eHighest' (given the Y axis coordinates + //increase downward so the 'highest' edge will have the smallest ytop) ... + TEdge *e = &edges[0]; + TEdge *eHighest = e; + do + { + e->xcurr = e->xbot; + e->ycurr = e->ybot; + if (e->ytop < eHighest->ytop) eHighest = e; + e = e->next; + } + while ( e != &edges[0]); + + //make sure eHighest is positioned so the following loop works safely ... + if (eHighest->windDelta > 0) eHighest = eHighest->next; + if (NEAR_EQUAL(eHighest->dx, HORIZONTAL)) eHighest = eHighest->next; + + //finally insert each local minima ... + e = eHighest; + do { + e = AddBoundsToLML(e); + } + while( e != eHighest ); + return true; +} +//------------------------------------------------------------------------------ + +void ClipperBase::InsertLocalMinima(LocalMinima *newLm) +{ + if( ! m_MinimaList ) + { + m_MinimaList = newLm; + } + else if( newLm->Y >= m_MinimaList->Y ) + { + newLm->next = m_MinimaList; + m_MinimaList = newLm; + } else + { + LocalMinima* tmpLm = m_MinimaList; + while( tmpLm->next && ( newLm->Y < tmpLm->next->Y ) ) + tmpLm = tmpLm->next; + newLm->next = tmpLm->next; + tmpLm->next = newLm; + } +} +//------------------------------------------------------------------------------ + +TEdge* ClipperBase::AddBoundsToLML(TEdge *e) +{ + //Starting at the top of one bound we progress to the bottom where there's + //a local minima. We then go to the top of the next bound. These two bounds + //form the left and right (or right and left) bounds of the local minima. + e->nextInLML = 0; + e = e->next; + for (;;) + { + if (NEAR_EQUAL(e->dx, HORIZONTAL)) + { + //nb: proceed through horizontals when approaching from their right, + // but break on horizontal minima if approaching from their left. + // This ensures 'local minima' are always on the left of horizontals. + if (e->next->ytop < e->ytop && e->next->xbot > e->prev->xbot) break; + if (e->xtop != e->prev->xbot) SwapX(*e); + e->nextInLML = e->prev; + } + else if (e->ycurr == e->prev->ycurr) break; + else e->nextInLML = e->prev; + e = e->next; + } + + //e and e.prev are now at a local minima ... + LocalMinima* newLm = new LocalMinima; + newLm->next = 0; + newLm->Y = e->prev->ybot; + + if ( NEAR_EQUAL(e->dx, HORIZONTAL) ) //horizontal edges never start a left bound + { + if (e->xbot != e->prev->xbot) SwapX(*e); + newLm->leftBound = e->prev; + newLm->rightBound = e; + } else if (e->dx < e->prev->dx) + { + newLm->leftBound = e->prev; + newLm->rightBound = e; + } else + { + newLm->leftBound = e; + newLm->rightBound = e->prev; + } + newLm->leftBound->side = esLeft; + newLm->rightBound->side = esRight; + InsertLocalMinima( newLm ); + + for (;;) + { + if ( e->next->ytop == e->ytop && !NEAR_EQUAL(e->next->dx, HORIZONTAL) ) break; + e->nextInLML = e->next; + e = e->next; + if ( NEAR_EQUAL(e->dx, HORIZONTAL) && e->xbot != e->prev->xtop) SwapX(*e); + } + return e->next; +} +//------------------------------------------------------------------------------ + +bool ClipperBase::AddPolygons(const Polygons &ppg, PolyType polyType) +{ + bool result = false; + for (Polygons::size_type i = 0; i < ppg.size(); ++i) + if (AddPolygon(ppg[i], polyType)) result = true; + return result; +} +//------------------------------------------------------------------------------ + +void ClipperBase::Clear() +{ + DisposeLocalMinimaList(); + for (EdgeList::size_type i = 0; i < m_edges.size(); ++i) delete [] m_edges[i]; + m_edges.clear(); + m_UseFullRange = false; +} +//------------------------------------------------------------------------------ + +void ClipperBase::Reset() +{ + m_CurrentLM = m_MinimaList; + if( !m_CurrentLM ) return; //ie nothing to process + + //reset all edges ... + LocalMinima* lm = m_MinimaList; + while( lm ) + { + TEdge* e = lm->leftBound; + while( e ) + { + e->xcurr = e->xbot; + e->ycurr = e->ybot; + e->side = esLeft; + e->outIdx = -1; + e = e->nextInLML; + } + e = lm->rightBound; + while( e ) + { + e->xcurr = e->xbot; + e->ycurr = e->ybot; + e->side = esRight; + e->outIdx = -1; + e = e->nextInLML; + } + lm = lm->next; + } +} +//------------------------------------------------------------------------------ + +void ClipperBase::DisposeLocalMinimaList() +{ + while( m_MinimaList ) + { + LocalMinima* tmpLm = m_MinimaList->next; + delete m_MinimaList; + m_MinimaList = tmpLm; + } + m_CurrentLM = 0; +} +//------------------------------------------------------------------------------ + +void ClipperBase::PopLocalMinima() +{ + if( ! m_CurrentLM ) return; + m_CurrentLM = m_CurrentLM->next; +} +//------------------------------------------------------------------------------ + +IntRect ClipperBase::GetBounds() +{ + IntRect result; + LocalMinima* lm = m_MinimaList; + if (!lm) + { + result.left = result.top = result.right = result.bottom = 0; + return result; + } + result.left = lm->leftBound->xbot; + result.top = lm->leftBound->ybot; + result.right = lm->leftBound->xbot; + result.bottom = lm->leftBound->ybot; + while (lm) + { + if (lm->leftBound->ybot > result.bottom) + result.bottom = lm->leftBound->ybot; + TEdge* e = lm->leftBound; + for (;;) { + TEdge* bottomE = e; + while (e->nextInLML) + { + if (e->xbot < result.left) result.left = e->xbot; + if (e->xbot > result.right) result.right = e->xbot; + e = e->nextInLML; + } + if (e->xbot < result.left) result.left = e->xbot; + if (e->xbot > result.right) result.right = e->xbot; + if (e->xtop < result.left) result.left = e->xtop; + if (e->xtop > result.right) result.right = e->xtop; + if (e->ytop < result.top) result.top = e->ytop; + + if (bottomE == lm->leftBound) e = lm->rightBound; + else break; + } + lm = lm->next; + } + return result; +} + + +//------------------------------------------------------------------------------ +// TClipper methods ... +//------------------------------------------------------------------------------ + +Clipper::Clipper() : ClipperBase() //constructor +{ + m_Scanbeam = 0; + m_ActiveEdges = 0; + m_SortedEdges = 0; + m_IntersectNodes = 0; + m_ExecuteLocked = false; + m_UseFullRange = false; + m_ReverseOutput = false; +} +//------------------------------------------------------------------------------ + +Clipper::~Clipper() //destructor +{ + Clear(); + DisposeScanbeamList(); +} +//------------------------------------------------------------------------------ + +void Clipper::Clear() +{ + if (m_edges.size() == 0) return; //avoids problems with ClipperBase destructor + DisposeAllPolyPts(); + ClipperBase::Clear(); +} +//------------------------------------------------------------------------------ + +void Clipper::DisposeScanbeamList() +{ + while ( m_Scanbeam ) { + Scanbeam* sb2 = m_Scanbeam->next; + delete m_Scanbeam; + m_Scanbeam = sb2; + } +} +//------------------------------------------------------------------------------ + +void Clipper::Reset() +{ + ClipperBase::Reset(); + m_Scanbeam = 0; + m_ActiveEdges = 0; + m_SortedEdges = 0; + DisposeAllPolyPts(); + LocalMinima* lm = m_MinimaList; + while (lm) + { + InsertScanbeam(lm->Y); + InsertScanbeam(lm->leftBound->ytop); + lm = lm->next; + } +} +//------------------------------------------------------------------------------ + +bool Clipper::Execute(ClipType clipType, Polygons &solution, + PolyFillType subjFillType, PolyFillType clipFillType) +{ + if( m_ExecuteLocked ) return false; + m_ExecuteLocked = true; + solution.resize(0); + m_SubjFillType = subjFillType; + m_ClipFillType = clipFillType; + m_ClipType = clipType; + bool succeeded = ExecuteInternal(false); + if (succeeded) BuildResult(solution); + m_ExecuteLocked = false; + return succeeded; +} +//------------------------------------------------------------------------------ + +bool Clipper::Execute(ClipType clipType, ExPolygons &solution, + PolyFillType subjFillType, PolyFillType clipFillType) +{ + if( m_ExecuteLocked ) return false; + m_ExecuteLocked = true; + solution.resize(0); + m_SubjFillType = subjFillType; + m_ClipFillType = clipFillType; + m_ClipType = clipType; + bool succeeded = ExecuteInternal(true); + if (succeeded) BuildResultEx(solution); + m_ExecuteLocked = false; + return succeeded; +} +//------------------------------------------------------------------------------ + +bool PolySort(OutRec *or1, OutRec *or2) +{ + if (or1 == or2) return false; + if (!or1->pts || !or2->pts) + { + if (or1->pts != or2->pts) + { + return or1->pts ? true : false; + } + else return false; + } + int i1, i2; + if (or1->isHole) + i1 = or1->FirstLeft->idx; else + i1 = or1->idx; + if (or2->isHole) + i2 = or2->FirstLeft->idx; else + i2 = or2->idx; + int result = i1 - i2; + if (result == 0 && (or1->isHole != or2->isHole)) + { + return or1->isHole ? false : true; + } + else return result < 0; +} +//------------------------------------------------------------------------------ + +OutRec* FindAppendLinkEnd(OutRec *outRec) +{ + while (outRec->AppendLink) outRec = outRec->AppendLink; + return outRec; +} +//------------------------------------------------------------------------------ + +void Clipper::FixHoleLinkage(OutRec *outRec) +{ + OutRec *tmp; + if (outRec->bottomPt) + tmp = m_PolyOuts[outRec->bottomPt->idx]->FirstLeft; + else + tmp = outRec->FirstLeft; + if (outRec == tmp) throw clipperException("HoleLinkage error"); + + if (tmp) + { + if (tmp->AppendLink) tmp = FindAppendLinkEnd(tmp); + if (tmp == outRec) tmp = 0; + else if (tmp->isHole) + { + FixHoleLinkage(tmp); + tmp = tmp->FirstLeft; + } + } + outRec->FirstLeft = tmp; + if (!tmp) outRec->isHole = false; + outRec->AppendLink = 0; +} +//------------------------------------------------------------------------------ + +bool Clipper::ExecuteInternal(bool fixHoleLinkages) +{ + bool succeeded; + try { + Reset(); + if (!m_CurrentLM ) return true; + long64 botY = PopScanbeam(); + do { + InsertLocalMinimaIntoAEL(botY); + ClearHorzJoins(); + ProcessHorizontals(); + long64 topY = PopScanbeam(); + succeeded = ProcessIntersections(botY, topY); + if (!succeeded) break; + ProcessEdgesAtTopOfScanbeam(topY); + botY = topY; + } while( m_Scanbeam ); + } + catch(...) { + succeeded = false; + } + + if (succeeded) + { + //tidy up output polygons and fix orientations where necessary ... + for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) + { + OutRec *outRec = m_PolyOuts[i]; + if (!outRec->pts) continue; + FixupOutPolygon(*outRec); + if (!outRec->pts) continue; + if (outRec->isHole && fixHoleLinkages) FixHoleLinkage(outRec); + + if (outRec->bottomPt == outRec->bottomFlag && + (Orientation(outRec, m_UseFullRange) != (Area(*outRec, m_UseFullRange) > 0))) + DisposeBottomPt(*outRec); + + if (outRec->isHole == + (m_ReverseOutput ^ Orientation(outRec, m_UseFullRange))) + ReversePolyPtLinks(*outRec->pts); + } + + JoinCommonEdges(fixHoleLinkages); + if (fixHoleLinkages) + std::sort(m_PolyOuts.begin(), m_PolyOuts.end(), PolySort); + } + + ClearJoins(); + ClearHorzJoins(); + return succeeded; +} +//------------------------------------------------------------------------------ + +void Clipper::InsertScanbeam(const long64 Y) +{ + if( !m_Scanbeam ) + { + m_Scanbeam = new Scanbeam; + m_Scanbeam->next = 0; + m_Scanbeam->Y = Y; + } + else if( Y > m_Scanbeam->Y ) + { + Scanbeam* newSb = new Scanbeam; + newSb->Y = Y; + newSb->next = m_Scanbeam; + m_Scanbeam = newSb; + } else + { + Scanbeam* sb2 = m_Scanbeam; + while( sb2->next && ( Y <= sb2->next->Y ) ) sb2 = sb2->next; + if( Y == sb2->Y ) return; //ie ignores duplicates + Scanbeam* newSb = new Scanbeam; + newSb->Y = Y; + newSb->next = sb2->next; + sb2->next = newSb; + } +} +//------------------------------------------------------------------------------ + +long64 Clipper::PopScanbeam() +{ + long64 Y = m_Scanbeam->Y; + Scanbeam* sb2 = m_Scanbeam; + m_Scanbeam = m_Scanbeam->next; + delete sb2; + return Y; +} +//------------------------------------------------------------------------------ + +void Clipper::DisposeAllPolyPts(){ + for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) + DisposeOutRec(i); + m_PolyOuts.clear(); +} +//------------------------------------------------------------------------------ + +void Clipper::DisposeOutRec(PolyOutList::size_type index) +{ + OutRec *outRec = m_PolyOuts[index]; + if (outRec->pts) DisposeOutPts(outRec->pts); + delete outRec; + m_PolyOuts[index] = 0; +} +//------------------------------------------------------------------------------ + +void Clipper::SetWindingCount(TEdge &edge) +{ + TEdge *e = edge.prevInAEL; + //find the edge of the same polytype that immediately preceeds 'edge' in AEL + while ( e && e->polyType != edge.polyType ) e = e->prevInAEL; + if ( !e ) + { + edge.windCnt = edge.windDelta; + edge.windCnt2 = 0; + e = m_ActiveEdges; //ie get ready to calc windCnt2 + } else if ( IsEvenOddFillType(edge) ) + { + //EvenOdd filling ... + edge.windCnt = 1; + edge.windCnt2 = e->windCnt2; + e = e->nextInAEL; //ie get ready to calc windCnt2 + } else + { + //nonZero, Positive or Negative filling ... + if ( e->windCnt * e->windDelta < 0 ) + { + if (Abs(e->windCnt) > 1) + { + if (e->windDelta * edge.windDelta < 0) edge.windCnt = e->windCnt; + else edge.windCnt = e->windCnt + edge.windDelta; + } else + edge.windCnt = e->windCnt + e->windDelta + edge.windDelta; + } else + { + if ( Abs(e->windCnt) > 1 && e->windDelta * edge.windDelta < 0) + edge.windCnt = e->windCnt; + else if ( e->windCnt + edge.windDelta == 0 ) + edge.windCnt = e->windCnt; + else edge.windCnt = e->windCnt + edge.windDelta; + } + edge.windCnt2 = e->windCnt2; + e = e->nextInAEL; //ie get ready to calc windCnt2 + } + + //update windCnt2 ... + if ( IsEvenOddAltFillType(edge) ) + { + //EvenOdd filling ... + while ( e != &edge ) + { + edge.windCnt2 = (edge.windCnt2 == 0) ? 1 : 0; + e = e->nextInAEL; + } + } else + { + //nonZero, Positive or Negative filling ... + while ( e != &edge ) + { + edge.windCnt2 += e->windDelta; + e = e->nextInAEL; + } + } +} +//------------------------------------------------------------------------------ + +bool Clipper::IsEvenOddFillType(const TEdge& edge) const +{ + if (edge.polyType == ptSubject) + return m_SubjFillType == pftEvenOdd; else + return m_ClipFillType == pftEvenOdd; +} +//------------------------------------------------------------------------------ + +bool Clipper::IsEvenOddAltFillType(const TEdge& edge) const +{ + if (edge.polyType == ptSubject) + return m_ClipFillType == pftEvenOdd; else + return m_SubjFillType == pftEvenOdd; +} +//------------------------------------------------------------------------------ + +bool Clipper::IsContributing(const TEdge& edge) const +{ + PolyFillType pft, pft2; + if (edge.polyType == ptSubject) + { + pft = m_SubjFillType; + pft2 = m_ClipFillType; + } else + { + pft = m_ClipFillType; + pft2 = m_SubjFillType; + } + + switch(pft) + { + case pftEvenOdd: + case pftNonZero: + if (Abs(edge.windCnt) != 1) return false; + break; + case pftPositive: + if (edge.windCnt != 1) return false; + break; + default: //pftNegative + if (edge.windCnt != -1) return false; + } + + switch(m_ClipType) + { + case ctIntersection: + switch(pft2) + { + case pftEvenOdd: + case pftNonZero: + return (edge.windCnt2 != 0); + case pftPositive: + return (edge.windCnt2 > 0); + default: + return (edge.windCnt2 < 0); + } + case ctUnion: + switch(pft2) + { + case pftEvenOdd: + case pftNonZero: + return (edge.windCnt2 == 0); + case pftPositive: + return (edge.windCnt2 <= 0); + default: + return (edge.windCnt2 >= 0); + } + case ctDifference: + if (edge.polyType == ptSubject) + switch(pft2) + { + case pftEvenOdd: + case pftNonZero: + return (edge.windCnt2 == 0); + case pftPositive: + return (edge.windCnt2 <= 0); + default: + return (edge.windCnt2 >= 0); + } + else + switch(pft2) + { + case pftEvenOdd: + case pftNonZero: + return (edge.windCnt2 != 0); + case pftPositive: + return (edge.windCnt2 > 0); + default: + return (edge.windCnt2 < 0); + } + default: + return true; + } +} +//------------------------------------------------------------------------------ + +void Clipper::AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &pt) +{ + TEdge *e, *prevE; + if( NEAR_EQUAL(e2->dx, HORIZONTAL) || ( e1->dx > e2->dx ) ) + { + AddOutPt( e1, pt ); + e2->outIdx = e1->outIdx; + e1->side = esLeft; + e2->side = esRight; + e = e1; + if (e->prevInAEL == e2) + prevE = e2->prevInAEL; + else + prevE = e->prevInAEL; + } else + { + AddOutPt( e2, pt ); + e1->outIdx = e2->outIdx; + e1->side = esRight; + e2->side = esLeft; + e = e2; + if (e->prevInAEL == e1) + prevE = e1->prevInAEL; + else + prevE = e->prevInAEL; + } + if (prevE && prevE->outIdx >= 0 && + (TopX(*prevE, pt.Y) == TopX(*e, pt.Y)) && + SlopesEqual(*e, *prevE, m_UseFullRange)) + AddJoin(e, prevE, -1, -1); +} +//------------------------------------------------------------------------------ + +void Clipper::AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &pt) +{ + AddOutPt( e1, pt ); + if( e1->outIdx == e2->outIdx ) + { + e1->outIdx = -1; + e2->outIdx = -1; + } + else if (e1->outIdx < e2->outIdx) + AppendPolygon(e1, e2); + else + AppendPolygon(e2, e1); +} +//------------------------------------------------------------------------------ + +void Clipper::AddEdgeToSEL(TEdge *edge) +{ + //SEL pointers in PEdge are reused to build a list of horizontal edges. + //However, we don't need to worry about order with horizontal edge processing. + if( !m_SortedEdges ) + { + m_SortedEdges = edge; + edge->prevInSEL = 0; + edge->nextInSEL = 0; + } + else + { + edge->nextInSEL = m_SortedEdges; + edge->prevInSEL = 0; + m_SortedEdges->prevInSEL = edge; + m_SortedEdges = edge; + } +} +//------------------------------------------------------------------------------ + +void Clipper::CopyAELToSEL() +{ + TEdge* e = m_ActiveEdges; + m_SortedEdges = e; + if (!m_ActiveEdges) return; + m_SortedEdges->prevInSEL = 0; + e = e->nextInAEL; + while ( e ) + { + e->prevInSEL = e->prevInAEL; + e->prevInSEL->nextInSEL = e; + e->nextInSEL = 0; + e = e->nextInAEL; + } +} +//------------------------------------------------------------------------------ + +void Clipper::AddJoin(TEdge *e1, TEdge *e2, int e1OutIdx, int e2OutIdx) +{ + JoinRec* jr = new JoinRec; + if (e1OutIdx >= 0) + jr->poly1Idx = e1OutIdx; else + jr->poly1Idx = e1->outIdx; + jr->pt1a = IntPoint(e1->xcurr, e1->ycurr); + jr->pt1b = IntPoint(e1->xtop, e1->ytop); + if (e2OutIdx >= 0) + jr->poly2Idx = e2OutIdx; else + jr->poly2Idx = e2->outIdx; + jr->pt2a = IntPoint(e2->xcurr, e2->ycurr); + jr->pt2b = IntPoint(e2->xtop, e2->ytop); + m_Joins.push_back(jr); +} +//------------------------------------------------------------------------------ + +void Clipper::ClearJoins() +{ + for (JoinList::size_type i = 0; i < m_Joins.size(); i++) + delete m_Joins[i]; + m_Joins.resize(0); +} +//------------------------------------------------------------------------------ + +void Clipper::AddHorzJoin(TEdge *e, int idx) +{ + HorzJoinRec* hj = new HorzJoinRec; + hj->edge = e; + hj->savedIdx = idx; + m_HorizJoins.push_back(hj); +} +//------------------------------------------------------------------------------ + +void Clipper::ClearHorzJoins() +{ + for (HorzJoinList::size_type i = 0; i < m_HorizJoins.size(); i++) + delete m_HorizJoins[i]; + m_HorizJoins.resize(0); +} +//------------------------------------------------------------------------------ + +void Clipper::InsertLocalMinimaIntoAEL( const long64 botY) +{ + while( m_CurrentLM && ( m_CurrentLM->Y == botY ) ) + { + TEdge* lb = m_CurrentLM->leftBound; + TEdge* rb = m_CurrentLM->rightBound; + + InsertEdgeIntoAEL( lb ); + InsertScanbeam( lb->ytop ); + InsertEdgeIntoAEL( rb ); + + if (IsEvenOddFillType(*lb)) + { + lb->windDelta = 1; + rb->windDelta = 1; + } + else + { + rb->windDelta = -lb->windDelta; + } + SetWindingCount( *lb ); + rb->windCnt = lb->windCnt; + rb->windCnt2 = lb->windCnt2; + + if( NEAR_EQUAL(rb->dx, HORIZONTAL) ) + { + //nb: only rightbounds can have a horizontal bottom edge + AddEdgeToSEL( rb ); + InsertScanbeam( rb->nextInLML->ytop ); + } + else + InsertScanbeam( rb->ytop ); + + if( IsContributing(*lb) ) + AddLocalMinPoly( lb, rb, IntPoint(lb->xcurr, m_CurrentLM->Y) ); + + //if any output polygons share an edge, they'll need joining later ... + if (rb->outIdx >= 0) + { + if (NEAR_EQUAL(rb->dx, HORIZONTAL)) + { + for (HorzJoinList::size_type i = 0; i < m_HorizJoins.size(); ++i) + { + IntPoint pt, pt2; //returned by GetOverlapSegment() but unused here. + HorzJoinRec* hj = m_HorizJoins[i]; + //if horizontals rb and hj.edge overlap, flag for joining later ... + if (GetOverlapSegment(IntPoint(hj->edge->xbot, hj->edge->ybot), + IntPoint(hj->edge->xtop, hj->edge->ytop), + IntPoint(rb->xbot, rb->ybot), + IntPoint(rb->xtop, rb->ytop), pt, pt2)) + AddJoin(hj->edge, rb, hj->savedIdx); + } + } + } + + if( lb->nextInAEL != rb ) + { + if (rb->outIdx >= 0 && rb->prevInAEL->outIdx >= 0 && + SlopesEqual(*rb->prevInAEL, *rb, m_UseFullRange)) + AddJoin(rb, rb->prevInAEL); + + TEdge* e = lb->nextInAEL; + IntPoint pt = IntPoint(lb->xcurr, lb->ycurr); + while( e != rb ) + { + if(!e) throw clipperException("InsertLocalMinimaIntoAEL: missing rightbound!"); + //nb: For calculating winding counts etc, IntersectEdges() assumes + //that param1 will be to the right of param2 ABOVE the intersection ... + IntersectEdges( rb , e , pt , ipNone); //order important here + e = e->nextInAEL; + } + } + PopLocalMinima(); + } +} +//------------------------------------------------------------------------------ + +void Clipper::DeleteFromAEL(TEdge *e) +{ + TEdge* AelPrev = e->prevInAEL; + TEdge* AelNext = e->nextInAEL; + if( !AelPrev && !AelNext && (e != m_ActiveEdges) ) return; //already deleted + if( AelPrev ) AelPrev->nextInAEL = AelNext; + else m_ActiveEdges = AelNext; + if( AelNext ) AelNext->prevInAEL = AelPrev; + e->nextInAEL = 0; + e->prevInAEL = 0; +} +//------------------------------------------------------------------------------ + +void Clipper::DeleteFromSEL(TEdge *e) +{ + TEdge* SelPrev = e->prevInSEL; + TEdge* SelNext = e->nextInSEL; + if( !SelPrev && !SelNext && (e != m_SortedEdges) ) return; //already deleted + if( SelPrev ) SelPrev->nextInSEL = SelNext; + else m_SortedEdges = SelNext; + if( SelNext ) SelNext->prevInSEL = SelPrev; + e->nextInSEL = 0; + e->prevInSEL = 0; +} +//------------------------------------------------------------------------------ + +void Clipper::IntersectEdges(TEdge *e1, TEdge *e2, + const IntPoint &pt, IntersectProtects protects) +{ + //e1 will be to the left of e2 BELOW the intersection. Therefore e1 is before + //e2 in AEL except when e1 is being inserted at the intersection point ... + bool e1stops = !(ipLeft & protects) && !e1->nextInLML && + e1->xtop == pt.X && e1->ytop == pt.Y; + bool e2stops = !(ipRight & protects) && !e2->nextInLML && + e2->xtop == pt.X && e2->ytop == pt.Y; + bool e1Contributing = ( e1->outIdx >= 0 ); + bool e2contributing = ( e2->outIdx >= 0 ); + + //update winding counts... + //assumes that e1 will be to the right of e2 ABOVE the intersection + if ( e1->polyType == e2->polyType ) + { + if ( IsEvenOddFillType( *e1) ) + { + int oldE1WindCnt = e1->windCnt; + e1->windCnt = e2->windCnt; + e2->windCnt = oldE1WindCnt; + } else + { + if (e1->windCnt + e2->windDelta == 0 ) e1->windCnt = -e1->windCnt; + else e1->windCnt += e2->windDelta; + if ( e2->windCnt - e1->windDelta == 0 ) e2->windCnt = -e2->windCnt; + else e2->windCnt -= e1->windDelta; + } + } else + { + if (!IsEvenOddFillType(*e2)) e1->windCnt2 += e2->windDelta; + else e1->windCnt2 = ( e1->windCnt2 == 0 ) ? 1 : 0; + if (!IsEvenOddFillType(*e1)) e2->windCnt2 -= e1->windDelta; + else e2->windCnt2 = ( e2->windCnt2 == 0 ) ? 1 : 0; + } + + PolyFillType e1FillType, e2FillType, e1FillType2, e2FillType2; + if (e1->polyType == ptSubject) + { + e1FillType = m_SubjFillType; + e1FillType2 = m_ClipFillType; + } else + { + e1FillType = m_ClipFillType; + e1FillType2 = m_SubjFillType; + } + if (e2->polyType == ptSubject) + { + e2FillType = m_SubjFillType; + e2FillType2 = m_ClipFillType; + } else + { + e2FillType = m_ClipFillType; + e2FillType2 = m_SubjFillType; + } + + long64 e1Wc, e2Wc; + switch (e1FillType) + { + case pftPositive: e1Wc = e1->windCnt; break; + case pftNegative: e1Wc = -e1->windCnt; break; + default: e1Wc = Abs(e1->windCnt); + } + switch(e2FillType) + { + case pftPositive: e2Wc = e2->windCnt; break; + case pftNegative: e2Wc = -e2->windCnt; break; + default: e2Wc = Abs(e2->windCnt); + } + + if ( e1Contributing && e2contributing ) + { + if ( e1stops || e2stops || + (e1Wc != 0 && e1Wc != 1) || (e2Wc != 0 && e2Wc != 1) || + (e1->polyType != e2->polyType && m_ClipType != ctXor) ) + AddLocalMaxPoly(e1, e2, pt); + else + DoBothEdges( e1, e2, pt ); + } + else if ( e1Contributing ) + { + if ((e2Wc == 0 || e2Wc == 1) && + (m_ClipType != ctIntersection || + e2->polyType == ptSubject || (e2->windCnt2 != 0))) + DoEdge1(e1, e2, pt); + } + else if ( e2contributing ) + { + if ((e1Wc == 0 || e1Wc == 1) && + (m_ClipType != ctIntersection || + e1->polyType == ptSubject || (e1->windCnt2 != 0))) + DoEdge2(e1, e2, pt); + } + else if ( (e1Wc == 0 || e1Wc == 1) && + (e2Wc == 0 || e2Wc == 1) && !e1stops && !e2stops ) + { + //neither edge is currently contributing ... + + long64 e1Wc2, e2Wc2; + switch (e1FillType2) + { + case pftPositive: e1Wc2 = e1->windCnt2; break; + case pftNegative : e1Wc2 = -e1->windCnt2; break; + default: e1Wc2 = Abs(e1->windCnt2); + } + switch (e2FillType2) + { + case pftPositive: e2Wc2 = e2->windCnt2; break; + case pftNegative: e2Wc2 = -e2->windCnt2; break; + default: e2Wc2 = Abs(e2->windCnt2); + } + + if (e1->polyType != e2->polyType) + AddLocalMinPoly(e1, e2, pt); + else if (e1Wc == 1 && e2Wc == 1) + switch( m_ClipType ) { + case ctIntersection: + if (e1Wc2 > 0 && e2Wc2 > 0) + AddLocalMinPoly(e1, e2, pt); + break; + case ctUnion: + if ( e1Wc2 <= 0 && e2Wc2 <= 0 ) + AddLocalMinPoly(e1, e2, pt); + break; + case ctDifference: + if (((e1->polyType == ptClip) && (e1Wc2 > 0) && (e2Wc2 > 0)) || + ((e1->polyType == ptSubject) && (e1Wc2 <= 0) && (e2Wc2 <= 0))) + AddLocalMinPoly(e1, e2, pt); + break; + case ctXor: + AddLocalMinPoly(e1, e2, pt); + } + else + SwapSides( *e1, *e2 ); + } + + if( (e1stops != e2stops) && + ( (e1stops && (e1->outIdx >= 0)) || (e2stops && (e2->outIdx >= 0)) ) ) + { + SwapSides( *e1, *e2 ); + SwapPolyIndexes( *e1, *e2 ); + } + + //finally, delete any non-contributing maxima edges ... + if( e1stops ) DeleteFromAEL( e1 ); + if( e2stops ) DeleteFromAEL( e2 ); +} +//------------------------------------------------------------------------------ + +void Clipper::SetHoleState(TEdge *e, OutRec *outRec) +{ + bool isHole = false; + TEdge *e2 = e->prevInAEL; + while (e2) + { + if (e2->outIdx >= 0) + { + isHole = !isHole; + if (! outRec->FirstLeft) + outRec->FirstLeft = m_PolyOuts[e2->outIdx]; + } + e2 = e2->prevInAEL; + } + if (isHole) outRec->isHole = true; +} +//------------------------------------------------------------------------------ + +OutRec* GetLowermostRec(OutRec *outRec1, OutRec *outRec2) +{ + //work out which polygon fragment has the correct hole state ... + OutPt *outPt1 = outRec1->bottomPt; + OutPt *outPt2 = outRec2->bottomPt; + if (outPt1->pt.Y > outPt2->pt.Y) return outRec1; + else if (outPt1->pt.Y < outPt2->pt.Y) return outRec2; + else if (outPt1->pt.X < outPt2->pt.X) return outRec1; + else if (outPt1->pt.X > outPt2->pt.X) return outRec2; + else if (outPt1->next == outPt1) return outRec2; + else if (outPt2->next == outPt2) return outRec1; + else if (FirstIsBottomPt(outPt1, outPt2)) return outRec1; + else return outRec2; +} +//------------------------------------------------------------------------------ + +bool Param1RightOfParam2(OutRec* outRec1, OutRec* outRec2) +{ + do + { + outRec1 = outRec1->FirstLeft; + if (outRec1 == outRec2) return true; + } while (outRec1); + return false; +} +//------------------------------------------------------------------------------ + +void Clipper::AppendPolygon(TEdge *e1, TEdge *e2) +{ + //get the start and ends of both output polygons ... + OutRec *outRec1 = m_PolyOuts[e1->outIdx]; + OutRec *outRec2 = m_PolyOuts[e2->outIdx]; + + OutRec *holeStateRec; + if (Param1RightOfParam2(outRec1, outRec2)) holeStateRec = outRec2; + else if (Param1RightOfParam2(outRec2, outRec1)) holeStateRec = outRec1; + else holeStateRec = GetLowermostRec(outRec1, outRec2); + + OutPt* p1_lft = outRec1->pts; + OutPt* p1_rt = p1_lft->prev; + OutPt* p2_lft = outRec2->pts; + OutPt* p2_rt = p2_lft->prev; + + EdgeSide side; + //join e2 poly onto e1 poly and delete pointers to e2 ... + if( e1->side == esLeft ) + { + if( e2->side == esLeft ) + { + //z y x a b c + ReversePolyPtLinks(*p2_lft); + p2_lft->next = p1_lft; + p1_lft->prev = p2_lft; + p1_rt->next = p2_rt; + p2_rt->prev = p1_rt; + outRec1->pts = p2_rt; + } else + { + //x y z a b c + p2_rt->next = p1_lft; + p1_lft->prev = p2_rt; + p2_lft->prev = p1_rt; + p1_rt->next = p2_lft; + outRec1->pts = p2_lft; + } + side = esLeft; + } else + { + if( e2->side == esRight ) + { + //a b c z y x + ReversePolyPtLinks( *p2_lft ); + p1_rt->next = p2_rt; + p2_rt->prev = p1_rt; + p2_lft->next = p1_lft; + p1_lft->prev = p2_lft; + } else + { + //a b c x y z + p1_rt->next = p2_lft; + p2_lft->prev = p1_rt; + p1_lft->prev = p2_rt; + p2_rt->next = p1_lft; + } + side = esRight; + } + + if (holeStateRec == outRec2) + { + outRec1->bottomPt = outRec2->bottomPt; + outRec1->bottomPt->idx = outRec1->idx; + if (outRec2->FirstLeft != outRec1) + outRec1->FirstLeft = outRec2->FirstLeft; + outRec1->isHole = outRec2->isHole; + } + outRec2->pts = 0; + outRec2->bottomPt = 0; + outRec2->AppendLink = outRec1; + int OKIdx = e1->outIdx; + int ObsoleteIdx = e2->outIdx; + + e1->outIdx = -1; //nb: safe because we only get here via AddLocalMaxPoly + e2->outIdx = -1; + + TEdge* e = m_ActiveEdges; + while( e ) + { + if( e->outIdx == ObsoleteIdx ) + { + e->outIdx = OKIdx; + e->side = side; + break; + } + e = e->nextInAEL; + } + + for (JoinList::size_type i = 0; i < m_Joins.size(); ++i) + { + if (m_Joins[i]->poly1Idx == ObsoleteIdx) m_Joins[i]->poly1Idx = OKIdx; + if (m_Joins[i]->poly2Idx == ObsoleteIdx) m_Joins[i]->poly2Idx = OKIdx; + } + + for (HorzJoinList::size_type i = 0; i < m_HorizJoins.size(); ++i) + { + if (m_HorizJoins[i]->savedIdx == ObsoleteIdx) + m_HorizJoins[i]->savedIdx = OKIdx; + } + +} +//------------------------------------------------------------------------------ + +OutRec* Clipper::CreateOutRec() +{ + OutRec* result = new OutRec; + result->isHole = false; + result->FirstLeft = 0; + result->AppendLink = 0; + result->pts = 0; + result->bottomPt = 0; + result->sides = esNeither; + result->bottomFlag = 0; + + return result; +} +//------------------------------------------------------------------------------ + +void Clipper::DisposeBottomPt(OutRec &outRec) +{ + OutPt* next = outRec.bottomPt->next; + OutPt* prev = outRec.bottomPt->prev; + if (outRec.pts == outRec.bottomPt) outRec.pts = next; + delete outRec.bottomPt; + next->prev = prev; + prev->next = next; + outRec.bottomPt = next; + FixupOutPolygon(outRec); +} +//------------------------------------------------------------------------------ + +void Clipper::AddOutPt(TEdge *e, const IntPoint &pt) +{ + bool ToFront = (e->side == esLeft); + if( e->outIdx < 0 ) + { + OutRec *outRec = CreateOutRec(); + m_PolyOuts.push_back(outRec); + outRec->idx = (int)m_PolyOuts.size()-1; + e->outIdx = outRec->idx; + OutPt* op = new OutPt; + outRec->pts = op; + outRec->bottomPt = op; + op->pt = pt; + op->idx = outRec->idx; + op->next = op; + op->prev = op; + SetHoleState(e, outRec); + } else + { + OutRec *outRec = m_PolyOuts[e->outIdx]; + OutPt* op = outRec->pts; + if ((ToFront && PointsEqual(pt, op->pt)) || + (!ToFront && PointsEqual(pt, op->prev->pt))) return; + + if ((e->side | outRec->sides) != outRec->sides) + { + //check for 'rounding' artefacts ... + if (outRec->sides == esNeither && pt.Y == op->pt.Y) + { + if (ToFront) + { + if (pt.X == op->pt.X +1) return; //ie wrong side of bottomPt + } + else if (pt.X == op->pt.X -1) return; //ie wrong side of bottomPt + } + + outRec->sides = (EdgeSide)(outRec->sides | e->side); + if (outRec->sides == esBoth) + { + //A vertex from each side has now been added. + //Vertices of one side of an output polygon are quite commonly close to + //or even 'touching' edges of the other side of the output polygon. + //Very occasionally vertices from one side can 'cross' an edge on the + //the other side. The distance 'crossed' is always less that a unit + //and is purely an artefact of coordinate rounding. Nevertheless, this + //results in very tiny self-intersections. Because of the way + //orientation is calculated, even tiny self-intersections can cause + //the Orientation function to return the wrong result. Therefore, it's + //important to ensure that any self-intersections close to BottomPt are + //detected and removed before orientation is assigned. + + OutPt *opBot, *op2; + if (ToFront) + { + opBot = outRec->pts; + op2 = opBot->next; //op2 == right side + if (opBot->pt.Y != op2->pt.Y && opBot->pt.Y != pt.Y && + ((opBot->pt.X - pt.X)/(opBot->pt.Y - pt.Y) < + (opBot->pt.X - op2->pt.X)/(opBot->pt.Y - op2->pt.Y))) + outRec->bottomFlag = opBot; + } else + { + opBot = outRec->pts->prev; + op2 = opBot->prev; //op2 == left side + if (opBot->pt.Y != op2->pt.Y && opBot->pt.Y != pt.Y && + ((opBot->pt.X - pt.X)/(opBot->pt.Y - pt.Y) > + (opBot->pt.X - op2->pt.X)/(opBot->pt.Y - op2->pt.Y))) + outRec->bottomFlag = opBot; + } + } + } + + OutPt* op2 = new OutPt; + op2->pt = pt; + op2->idx = outRec->idx; + if (op2->pt.Y == outRec->bottomPt->pt.Y && + op2->pt.X < outRec->bottomPt->pt.X) + outRec->bottomPt = op2; + op2->next = op; + op2->prev = op->prev; + op2->prev->next = op2; + op->prev = op2; + if (ToFront) outRec->pts = op2; + } +} +//------------------------------------------------------------------------------ + +void Clipper::ProcessHorizontals() +{ + TEdge* horzEdge = m_SortedEdges; + while( horzEdge ) + { + DeleteFromSEL( horzEdge ); + ProcessHorizontal( horzEdge ); + horzEdge = m_SortedEdges; + } +} +//------------------------------------------------------------------------------ + +bool Clipper::IsTopHorz(const long64 XPos) +{ + TEdge* e = m_SortedEdges; + while( e ) + { + if( ( XPos >= std::min(e->xcurr, e->xtop) ) && + ( XPos <= std::max(e->xcurr, e->xtop) ) ) return false; + e = e->nextInSEL; + } + return true; +} +//------------------------------------------------------------------------------ + +bool IsMinima(TEdge *e) +{ + return e && (e->prev->nextInLML != e) && (e->next->nextInLML != e); +} +//------------------------------------------------------------------------------ + +bool IsMaxima(TEdge *e, const long64 Y) +{ + return e && e->ytop == Y && !e->nextInLML; +} +//------------------------------------------------------------------------------ + +bool IsIntermediate(TEdge *e, const long64 Y) +{ + return e->ytop == Y && e->nextInLML; +} +//------------------------------------------------------------------------------ + +TEdge *GetMaximaPair(TEdge *e) +{ + if( !IsMaxima(e->next, e->ytop) || e->next->xtop != e->xtop ) + return e->prev; else + return e->next; +} +//------------------------------------------------------------------------------ + +void Clipper::SwapPositionsInAEL(TEdge *edge1, TEdge *edge2) +{ + if( !edge1->nextInAEL && !edge1->prevInAEL ) return; + if( !edge2->nextInAEL && !edge2->prevInAEL ) return; + + if( edge1->nextInAEL == edge2 ) + { + TEdge* next = edge2->nextInAEL; + if( next ) next->prevInAEL = edge1; + TEdge* prev = edge1->prevInAEL; + if( prev ) prev->nextInAEL = edge2; + edge2->prevInAEL = prev; + edge2->nextInAEL = edge1; + edge1->prevInAEL = edge2; + edge1->nextInAEL = next; + } + else if( edge2->nextInAEL == edge1 ) + { + TEdge* next = edge1->nextInAEL; + if( next ) next->prevInAEL = edge2; + TEdge* prev = edge2->prevInAEL; + if( prev ) prev->nextInAEL = edge1; + edge1->prevInAEL = prev; + edge1->nextInAEL = edge2; + edge2->prevInAEL = edge1; + edge2->nextInAEL = next; + } + else + { + TEdge* next = edge1->nextInAEL; + TEdge* prev = edge1->prevInAEL; + edge1->nextInAEL = edge2->nextInAEL; + if( edge1->nextInAEL ) edge1->nextInAEL->prevInAEL = edge1; + edge1->prevInAEL = edge2->prevInAEL; + if( edge1->prevInAEL ) edge1->prevInAEL->nextInAEL = edge1; + edge2->nextInAEL = next; + if( edge2->nextInAEL ) edge2->nextInAEL->prevInAEL = edge2; + edge2->prevInAEL = prev; + if( edge2->prevInAEL ) edge2->prevInAEL->nextInAEL = edge2; + } + + if( !edge1->prevInAEL ) m_ActiveEdges = edge1; + else if( !edge2->prevInAEL ) m_ActiveEdges = edge2; +} +//------------------------------------------------------------------------------ + +void Clipper::SwapPositionsInSEL(TEdge *edge1, TEdge *edge2) +{ + if( !( edge1->nextInSEL ) && !( edge1->prevInSEL ) ) return; + if( !( edge2->nextInSEL ) && !( edge2->prevInSEL ) ) return; + + if( edge1->nextInSEL == edge2 ) + { + TEdge* next = edge2->nextInSEL; + if( next ) next->prevInSEL = edge1; + TEdge* prev = edge1->prevInSEL; + if( prev ) prev->nextInSEL = edge2; + edge2->prevInSEL = prev; + edge2->nextInSEL = edge1; + edge1->prevInSEL = edge2; + edge1->nextInSEL = next; + } + else if( edge2->nextInSEL == edge1 ) + { + TEdge* next = edge1->nextInSEL; + if( next ) next->prevInSEL = edge2; + TEdge* prev = edge2->prevInSEL; + if( prev ) prev->nextInSEL = edge1; + edge1->prevInSEL = prev; + edge1->nextInSEL = edge2; + edge2->prevInSEL = edge1; + edge2->nextInSEL = next; + } + else + { + TEdge* next = edge1->nextInSEL; + TEdge* prev = edge1->prevInSEL; + edge1->nextInSEL = edge2->nextInSEL; + if( edge1->nextInSEL ) edge1->nextInSEL->prevInSEL = edge1; + edge1->prevInSEL = edge2->prevInSEL; + if( edge1->prevInSEL ) edge1->prevInSEL->nextInSEL = edge1; + edge2->nextInSEL = next; + if( edge2->nextInSEL ) edge2->nextInSEL->prevInSEL = edge2; + edge2->prevInSEL = prev; + if( edge2->prevInSEL ) edge2->prevInSEL->nextInSEL = edge2; + } + + if( !edge1->prevInSEL ) m_SortedEdges = edge1; + else if( !edge2->prevInSEL ) m_SortedEdges = edge2; +} +//------------------------------------------------------------------------------ + +TEdge* GetNextInAEL(TEdge *e, Direction dir) +{ + return dir == dLeftToRight ? e->nextInAEL : e->prevInAEL; +} +//------------------------------------------------------------------------------ + +void Clipper::ProcessHorizontal(TEdge *horzEdge) +{ + Direction dir; + long64 horzLeft, horzRight; + + if( horzEdge->xcurr < horzEdge->xtop ) + { + horzLeft = horzEdge->xcurr; + horzRight = horzEdge->xtop; + dir = dLeftToRight; + } else + { + horzLeft = horzEdge->xtop; + horzRight = horzEdge->xcurr; + dir = dRightToLeft; + } + + TEdge* eMaxPair; + if( horzEdge->nextInLML ) eMaxPair = 0; + else eMaxPair = GetMaximaPair(horzEdge); + + TEdge* e = GetNextInAEL( horzEdge , dir ); + while( e ) + { + TEdge* eNext = GetNextInAEL( e, dir ); + + if (eMaxPair || + ((dir == dLeftToRight) && (e->xcurr <= horzRight)) || + ((dir == dRightToLeft) && (e->xcurr >= horzLeft))) + { + //ok, so far it looks like we're still in range of the horizontal edge + if ( e->xcurr == horzEdge->xtop && !eMaxPair ) + { + if (SlopesEqual(*e, *horzEdge->nextInLML, m_UseFullRange)) + { + //if output polygons share an edge, they'll need joining later ... + if (horzEdge->outIdx >= 0 && e->outIdx >= 0) + AddJoin(horzEdge->nextInLML, e, horzEdge->outIdx); + break; //we've reached the end of the horizontal line + } + else if (e->dx < horzEdge->nextInLML->dx) + //we really have got to the end of the intermediate horz edge so quit. + //nb: More -ve slopes follow more +ve slopes ABOVE the horizontal. + break; + } + + if( e == eMaxPair ) + { + //horzEdge is evidently a maxima horizontal and we've arrived at its end. + if (dir == dLeftToRight) + IntersectEdges(horzEdge, e, IntPoint(e->xcurr, horzEdge->ycurr), ipNone); + else + IntersectEdges(e, horzEdge, IntPoint(e->xcurr, horzEdge->ycurr), ipNone); + if (eMaxPair->outIdx >= 0) throw clipperException("ProcessHorizontal error"); + return; + } + else if( NEAR_EQUAL(e->dx, HORIZONTAL) && !IsMinima(e) && !(e->xcurr > e->xtop) ) + { + //An overlapping horizontal edge. Overlapping horizontal edges are + //processed as if layered with the current horizontal edge (horizEdge) + //being infinitesimally lower that the next (e). Therfore, we + //intersect with e only if e.xcurr is within the bounds of horzEdge ... + if( dir == dLeftToRight ) + IntersectEdges( horzEdge , e, IntPoint(e->xcurr, horzEdge->ycurr), + (IsTopHorz( e->xcurr ))? ipLeft : ipBoth ); + else + IntersectEdges( e, horzEdge, IntPoint(e->xcurr, horzEdge->ycurr), + (IsTopHorz( e->xcurr ))? ipRight : ipBoth ); + } + else if( dir == dLeftToRight ) + { + IntersectEdges( horzEdge, e, IntPoint(e->xcurr, horzEdge->ycurr), + (IsTopHorz( e->xcurr ))? ipLeft : ipBoth ); + } + else + { + IntersectEdges( e, horzEdge, IntPoint(e->xcurr, horzEdge->ycurr), + (IsTopHorz( e->xcurr ))? ipRight : ipBoth ); + } + SwapPositionsInAEL( horzEdge, e ); + } + else if( (dir == dLeftToRight && e->xcurr > horzRight && m_SortedEdges) || + (dir == dRightToLeft && e->xcurr < horzLeft && m_SortedEdges) ) break; + e = eNext; + } //end while + + if( horzEdge->nextInLML ) + { + if( horzEdge->outIdx >= 0 ) + AddOutPt( horzEdge, IntPoint(horzEdge->xtop, horzEdge->ytop)); + UpdateEdgeIntoAEL( horzEdge ); + } + else + { + if ( horzEdge->outIdx >= 0 ) + IntersectEdges( horzEdge, eMaxPair, + IntPoint(horzEdge->xtop, horzEdge->ycurr), ipBoth); + if (eMaxPair->outIdx >= 0) throw clipperException("ProcessHorizontal error"); + DeleteFromAEL(eMaxPair); + DeleteFromAEL(horzEdge); + } +} +//------------------------------------------------------------------------------ + +void Clipper::UpdateEdgeIntoAEL(TEdge *&e) +{ + if( !e->nextInLML ) throw + clipperException("UpdateEdgeIntoAEL: invalid call"); + TEdge* AelPrev = e->prevInAEL; + TEdge* AelNext = e->nextInAEL; + e->nextInLML->outIdx = e->outIdx; + if( AelPrev ) AelPrev->nextInAEL = e->nextInLML; + else m_ActiveEdges = e->nextInLML; + if( AelNext ) AelNext->prevInAEL = e->nextInLML; + e->nextInLML->side = e->side; + e->nextInLML->windDelta = e->windDelta; + e->nextInLML->windCnt = e->windCnt; + e->nextInLML->windCnt2 = e->windCnt2; + e = e->nextInLML; + e->prevInAEL = AelPrev; + e->nextInAEL = AelNext; + if( !NEAR_EQUAL(e->dx, HORIZONTAL) ) InsertScanbeam( e->ytop ); +} +//------------------------------------------------------------------------------ + +bool Clipper::ProcessIntersections(const long64 botY, const long64 topY) +{ + if( !m_ActiveEdges ) return true; + try { + BuildIntersectList(botY, topY); + if ( !m_IntersectNodes) return true; + if ( FixupIntersections() ) ProcessIntersectList(); + else return false; + } + catch(...) { + m_SortedEdges = 0; + DisposeIntersectNodes(); + throw clipperException("ProcessIntersections error"); + } + return true; +} +//------------------------------------------------------------------------------ + +void Clipper::DisposeIntersectNodes() +{ + while ( m_IntersectNodes ) + { + IntersectNode* iNode = m_IntersectNodes->next; + delete m_IntersectNodes; + m_IntersectNodes = iNode; + } +} +//------------------------------------------------------------------------------ + +void Clipper::BuildIntersectList(const long64 botY, const long64 topY) +{ + if ( !m_ActiveEdges ) return; + + //prepare for sorting ... + TEdge* e = m_ActiveEdges; + e->tmpX = TopX( *e, topY ); + m_SortedEdges = e; + m_SortedEdges->prevInSEL = 0; + e = e->nextInAEL; + while( e ) + { + e->prevInSEL = e->prevInAEL; + e->prevInSEL->nextInSEL = e; + e->nextInSEL = 0; + e->tmpX = TopX( *e, topY ); + e = e->nextInAEL; + } + + //bubblesort ... + bool isModified = true; + while( isModified && m_SortedEdges ) + { + isModified = false; + e = m_SortedEdges; + while( e->nextInSEL ) + { + TEdge *eNext = e->nextInSEL; + IntPoint pt; + if(e->tmpX > eNext->tmpX && + IntersectPoint(*e, *eNext, pt, m_UseFullRange)) + { + if (pt.Y > botY) + { + pt.Y = botY; + pt.X = TopX(*e, pt.Y); + } + AddIntersectNode( e, eNext, pt ); + SwapPositionsInSEL(e, eNext); + isModified = true; + } + else + e = eNext; + } + if( e->prevInSEL ) e->prevInSEL->nextInSEL = 0; + else break; + } + m_SortedEdges = 0; +} +//------------------------------------------------------------------------------ + +bool ProcessParam1BeforeParam2(IntersectNode &node1, IntersectNode &node2) +{ + bool result; + if (node1.pt.Y == node2.pt.Y) + { + if (node1.edge1 == node2.edge1 || node1.edge2 == node2.edge1) + { + result = node2.pt.X > node1.pt.X; + return node2.edge1->dx > 0 ? !result : result; + } + else if (node1.edge1 == node2.edge2 || node1.edge2 == node2.edge2) + { + result = node2.pt.X > node1.pt.X; + return node2.edge2->dx > 0 ? !result : result; + } + else return node2.pt.X > node1.pt.X; + } + else return node1.pt.Y > node2.pt.Y; +} +//------------------------------------------------------------------------------ + +void Clipper::AddIntersectNode(TEdge *e1, TEdge *e2, const IntPoint &pt) +{ + IntersectNode* newNode = new IntersectNode; + newNode->edge1 = e1; + newNode->edge2 = e2; + newNode->pt = pt; + newNode->next = 0; + if( !m_IntersectNodes ) m_IntersectNodes = newNode; + else if( ProcessParam1BeforeParam2(*newNode, *m_IntersectNodes) ) + { + newNode->next = m_IntersectNodes; + m_IntersectNodes = newNode; + } + else + { + IntersectNode* iNode = m_IntersectNodes; + while( iNode->next && ProcessParam1BeforeParam2(*iNode->next, *newNode) ) + iNode = iNode->next; + newNode->next = iNode->next; + iNode->next = newNode; + } +} +//------------------------------------------------------------------------------ + +void Clipper::ProcessIntersectList() +{ + while( m_IntersectNodes ) + { + IntersectNode* iNode = m_IntersectNodes->next; + { + IntersectEdges( m_IntersectNodes->edge1 , + m_IntersectNodes->edge2 , m_IntersectNodes->pt, ipBoth ); + SwapPositionsInAEL( m_IntersectNodes->edge1 , m_IntersectNodes->edge2 ); + } + delete m_IntersectNodes; + m_IntersectNodes = iNode; + } +} +//------------------------------------------------------------------------------ + +void Clipper::DoMaxima(TEdge *e, long64 topY) +{ + TEdge* eMaxPair = GetMaximaPair(e); + long64 X = e->xtop; + TEdge* eNext = e->nextInAEL; + while( eNext != eMaxPair ) + { + if (!eNext) throw clipperException("DoMaxima error"); + IntersectEdges( e, eNext, IntPoint(X, topY), ipBoth ); + eNext = eNext->nextInAEL; + } + if( e->outIdx < 0 && eMaxPair->outIdx < 0 ) + { + DeleteFromAEL( e ); + DeleteFromAEL( eMaxPair ); + } + else if( e->outIdx >= 0 && eMaxPair->outIdx >= 0 ) + { + IntersectEdges( e, eMaxPair, IntPoint(X, topY), ipNone ); + } + else throw clipperException("DoMaxima error"); +} +//------------------------------------------------------------------------------ + +void Clipper::ProcessEdgesAtTopOfScanbeam(const long64 topY) +{ + TEdge* e = m_ActiveEdges; + while( e ) + { + //1. process maxima, treating them as if they're 'bent' horizontal edges, + // but exclude maxima with horizontal edges. nb: e can't be a horizontal. + if( IsMaxima(e, topY) && !NEAR_EQUAL(GetMaximaPair(e)->dx, HORIZONTAL) ) + { + //'e' might be removed from AEL, as may any following edges so ... + TEdge* ePrior = e->prevInAEL; + DoMaxima(e, topY); + if( !ePrior ) e = m_ActiveEdges; + else e = ePrior->nextInAEL; + } + else + { + //2. promote horizontal edges, otherwise update xcurr and ycurr ... + if( IsIntermediate(e, topY) && NEAR_EQUAL(e->nextInLML->dx, HORIZONTAL) ) + { + if (e->outIdx >= 0) + { + AddOutPt(e, IntPoint(e->xtop, e->ytop)); + + for (HorzJoinList::size_type i = 0; i < m_HorizJoins.size(); ++i) + { + IntPoint pt, pt2; + HorzJoinRec* hj = m_HorizJoins[i]; + if (GetOverlapSegment(IntPoint(hj->edge->xbot, hj->edge->ybot), + IntPoint(hj->edge->xtop, hj->edge->ytop), + IntPoint(e->nextInLML->xbot, e->nextInLML->ybot), + IntPoint(e->nextInLML->xtop, e->nextInLML->ytop), pt, pt2)) + AddJoin(hj->edge, e->nextInLML, hj->savedIdx, e->outIdx); + } + + AddHorzJoin(e->nextInLML, e->outIdx); + } + UpdateEdgeIntoAEL(e); + AddEdgeToSEL(e); + } else + { + //this just simplifies horizontal processing ... + e->xcurr = TopX( *e, topY ); + e->ycurr = topY; + } + e = e->nextInAEL; + } + } + + //3. Process horizontals at the top of the scanbeam ... + ProcessHorizontals(); + + //4. Promote intermediate vertices ... + e = m_ActiveEdges; + while( e ) + { + if( IsIntermediate( e, topY ) ) + { + if( e->outIdx >= 0 ) AddOutPt(e, IntPoint(e->xtop,e->ytop)); + UpdateEdgeIntoAEL(e); + + //if output polygons share an edge, they'll need joining later ... + if (e->outIdx >= 0 && e->prevInAEL && e->prevInAEL->outIdx >= 0 && + e->prevInAEL->xcurr == e->xbot && e->prevInAEL->ycurr == e->ybot && + SlopesEqual(IntPoint(e->xbot,e->ybot), IntPoint(e->xtop, e->ytop), + IntPoint(e->xbot,e->ybot), + IntPoint(e->prevInAEL->xtop, e->prevInAEL->ytop), m_UseFullRange)) + { + AddOutPt(e->prevInAEL, IntPoint(e->xbot, e->ybot)); + AddJoin(e, e->prevInAEL); + } + else if (e->outIdx >= 0 && e->nextInAEL && e->nextInAEL->outIdx >= 0 && + e->nextInAEL->ycurr > e->nextInAEL->ytop && + e->nextInAEL->ycurr <= e->nextInAEL->ybot && + e->nextInAEL->xcurr == e->xbot && e->nextInAEL->ycurr == e->ybot && + SlopesEqual(IntPoint(e->xbot,e->ybot), IntPoint(e->xtop, e->ytop), + IntPoint(e->xbot,e->ybot), + IntPoint(e->nextInAEL->xtop, e->nextInAEL->ytop), m_UseFullRange)) + { + AddOutPt(e->nextInAEL, IntPoint(e->xbot, e->ybot)); + AddJoin(e, e->nextInAEL); + } + } + e = e->nextInAEL; + } +} +//------------------------------------------------------------------------------ + +void Clipper::FixupOutPolygon(OutRec &outRec) +{ + //FixupOutPolygon() - removes duplicate points and simplifies consecutive + //parallel edges by removing the middle vertex. + OutPt *lastOK = 0; + outRec.pts = outRec.bottomPt; + OutPt *pp = outRec.bottomPt; + + for (;;) + { + if (pp->prev == pp || pp->prev == pp->next ) + { + DisposeOutPts(pp); + outRec.pts = 0; + outRec.bottomPt = 0; + return; + } + //test for duplicate points and for same slope (cross-product) ... + if ( PointsEqual(pp->pt, pp->next->pt) || + SlopesEqual(pp->prev->pt, pp->pt, pp->next->pt, m_UseFullRange) ) + { + lastOK = 0; + OutPt *tmp = pp; + if (pp == outRec.bottomPt) + outRec.bottomPt = 0; //flags need for updating + pp->prev->next = pp->next; + pp->next->prev = pp->prev; + pp = pp->prev; + delete tmp; + } + else if (pp == lastOK) break; + else + { + if (!lastOK) lastOK = pp; + pp = pp->next; + } + } + if (!outRec.bottomPt) { + outRec.bottomPt = GetBottomPt(pp); + outRec.bottomPt->idx = outRec.idx; + outRec.pts = outRec.bottomPt; + } +} +//------------------------------------------------------------------------------ + +void Clipper::BuildResult(Polygons &polys) +{ + int k = 0; + polys.resize(m_PolyOuts.size()); + for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) + { + if (m_PolyOuts[i]->pts) + { + Polygon* pg = &polys[k]; + pg->clear(); + OutPt* p = m_PolyOuts[i]->pts; + do + { + pg->push_back(p->pt); + p = p->next; + } while (p != m_PolyOuts[i]->pts); + //make sure each polygon has at least 3 vertices ... + if (pg->size() < 3) pg->clear(); else k++; + } + } + polys.resize(k); +} +//------------------------------------------------------------------------------ + +void Clipper::BuildResultEx(ExPolygons &polys) +{ + PolyOutList::size_type i = 0; + int k = 0; + polys.resize(0); + polys.reserve(m_PolyOuts.size()); + while (i < m_PolyOuts.size() && m_PolyOuts[i]->pts) + { + ExPolygon epg; + OutPt* p = m_PolyOuts[i]->pts; + do { + epg.outer.push_back(p->pt); + p = p->next; + } while (p != m_PolyOuts[i]->pts); + i++; + //make sure polygons have at least 3 vertices ... + if (epg.outer.size() < 3) continue; + while (i < m_PolyOuts.size() + && m_PolyOuts[i]->pts && m_PolyOuts[i]->isHole) + { + Polygon pg; + p = m_PolyOuts[i]->pts; + do { + pg.push_back(p->pt); + p = p->next; + } while (p != m_PolyOuts[i]->pts); + epg.holes.push_back(pg); + i++; + } + polys.push_back(epg); + k++; + } + polys.resize(k); +} +//------------------------------------------------------------------------------ + +void SwapIntersectNodes(IntersectNode &int1, IntersectNode &int2) +{ + TEdge *e1 = int1.edge1; + TEdge *e2 = int1.edge2; + IntPoint p = int1.pt; + + int1.edge1 = int2.edge1; + int1.edge2 = int2.edge2; + int1.pt = int2.pt; + + int2.edge1 = e1; + int2.edge2 = e2; + int2.pt = p; +} +//------------------------------------------------------------------------------ + +bool Clipper::FixupIntersections() +{ + if ( !m_IntersectNodes->next ) return true; + + CopyAELToSEL(); + IntersectNode *int1 = m_IntersectNodes; + IntersectNode *int2 = m_IntersectNodes->next; + while (int2) + { + TEdge *e1 = int1->edge1; + TEdge *e2; + if (e1->prevInSEL == int1->edge2) e2 = e1->prevInSEL; + else if (e1->nextInSEL == int1->edge2) e2 = e1->nextInSEL; + else + { + //The current intersection is out of order, so try and swap it with + //a subsequent intersection ... + while (int2) + { + if (int2->edge1->nextInSEL == int2->edge2 || + int2->edge1->prevInSEL == int2->edge2) break; + else int2 = int2->next; + } + if ( !int2 ) return false; //oops!!! + + //found an intersect node that can be swapped ... + SwapIntersectNodes(*int1, *int2); + e1 = int1->edge1; + e2 = int1->edge2; + } + SwapPositionsInSEL(e1, e2); + int1 = int1->next; + int2 = int1->next; + } + + m_SortedEdges = 0; + + //finally, check the last intersection too ... + return (int1->edge1->prevInSEL == int1->edge2 || + int1->edge1->nextInSEL == int1->edge2); +} +//------------------------------------------------------------------------------ + +bool E2InsertsBeforeE1(TEdge &e1, TEdge &e2) +{ + return e2.xcurr == e1.xcurr ? e2.dx > e1.dx : e2.xcurr < e1.xcurr; +} +//------------------------------------------------------------------------------ + +void Clipper::InsertEdgeIntoAEL(TEdge *edge) +{ + edge->prevInAEL = 0; + edge->nextInAEL = 0; + if( !m_ActiveEdges ) + { + m_ActiveEdges = edge; + } + else if( E2InsertsBeforeE1(*m_ActiveEdges, *edge) ) + { + edge->nextInAEL = m_ActiveEdges; + m_ActiveEdges->prevInAEL = edge; + m_ActiveEdges = edge; + } else + { + TEdge* e = m_ActiveEdges; + while( e->nextInAEL && !E2InsertsBeforeE1(*e->nextInAEL , *edge) ) + e = e->nextInAEL; + edge->nextInAEL = e->nextInAEL; + if( e->nextInAEL ) e->nextInAEL->prevInAEL = edge; + edge->prevInAEL = e; + e->nextInAEL = edge; + } +} +//---------------------------------------------------------------------- + +void Clipper::DoEdge1(TEdge *edge1, TEdge *edge2, const IntPoint &pt) +{ + AddOutPt(edge1, pt); + SwapSides(*edge1, *edge2); + SwapPolyIndexes(*edge1, *edge2); +} +//---------------------------------------------------------------------- + +void Clipper::DoEdge2(TEdge *edge1, TEdge *edge2, const IntPoint &pt) +{ + AddOutPt(edge2, pt); + SwapSides(*edge1, *edge2); + SwapPolyIndexes(*edge1, *edge2); +} +//---------------------------------------------------------------------- + +void Clipper::DoBothEdges(TEdge *edge1, TEdge *edge2, const IntPoint &pt) +{ + AddOutPt(edge1, pt); + AddOutPt(edge2, pt); + SwapSides( *edge1 , *edge2 ); + SwapPolyIndexes( *edge1 , *edge2 ); +} +//---------------------------------------------------------------------- + +void Clipper::CheckHoleLinkages1(OutRec *outRec1, OutRec *outRec2) +{ + //when a polygon is split into 2 polygons, make sure any holes the original + //polygon contained link to the correct polygon ... + for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) + { + OutRec *orec = m_PolyOuts[i]; + if (orec->isHole && orec->bottomPt && orec->FirstLeft == outRec1 && + !PointInPolygon(orec->bottomPt->pt, outRec1->pts, m_UseFullRange)) + orec->FirstLeft = outRec2; + } +} +//---------------------------------------------------------------------- + +void Clipper::CheckHoleLinkages2(OutRec *outRec1, OutRec *outRec2) +{ + //if a hole is owned by outRec2 then make it owned by outRec1 ... + for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) + if (m_PolyOuts[i]->isHole && m_PolyOuts[i]->bottomPt && + m_PolyOuts[i]->FirstLeft == outRec2) + m_PolyOuts[i]->FirstLeft = outRec1; +} +//---------------------------------------------------------------------- + +void Clipper::JoinCommonEdges(bool fixHoleLinkages) +{ + for (JoinList::size_type i = 0; i < m_Joins.size(); i++) + { + JoinRec* j = m_Joins[i]; + OutRec *outRec1 = m_PolyOuts[j->poly1Idx]; + OutPt *pp1a = outRec1->pts; + OutRec *outRec2 = m_PolyOuts[j->poly2Idx]; + OutPt *pp2a = outRec2->pts; + IntPoint pt1 = j->pt2a, pt2 = j->pt2b; + IntPoint pt3 = j->pt1a, pt4 = j->pt1b; + if (!FindSegment(pp1a, pt1, pt2)) continue; + if (j->poly1Idx == j->poly2Idx) + { + //we're searching the same polygon for overlapping segments so + //segment 2 mustn't be the same as segment 1 ... + pp2a = pp1a->next; + if (!FindSegment(pp2a, pt3, pt4) || (pp2a == pp1a)) continue; + } + else if (!FindSegment(pp2a, pt3, pt4)) continue; + + if (!GetOverlapSegment(pt1, pt2, pt3, pt4, pt1, pt2)) continue; + + OutPt *p1, *p2, *p3, *p4; + OutPt *prev = pp1a->prev; + //get p1 & p2 polypts - the overlap start & endpoints on poly1 + if (PointsEqual(pp1a->pt, pt1)) p1 = pp1a; + else if (PointsEqual(prev->pt, pt1)) p1 = prev; + else p1 = InsertPolyPtBetween(pp1a, prev, pt1); + + if (PointsEqual(pp1a->pt, pt2)) p2 = pp1a; + else if (PointsEqual(prev->pt, pt2)) p2 = prev; + else if ((p1 == pp1a) || (p1 == prev)) + p2 = InsertPolyPtBetween(pp1a, prev, pt2); + else if (Pt3IsBetweenPt1AndPt2(pp1a->pt, p1->pt, pt2)) + p2 = InsertPolyPtBetween(pp1a, p1, pt2); else + p2 = InsertPolyPtBetween(p1, prev, pt2); + + //get p3 & p4 polypts - the overlap start & endpoints on poly2 + prev = pp2a->prev; + if (PointsEqual(pp2a->pt, pt1)) p3 = pp2a; + else if (PointsEqual(prev->pt, pt1)) p3 = prev; + else p3 = InsertPolyPtBetween(pp2a, prev, pt1); + + if (PointsEqual(pp2a->pt, pt2)) p4 = pp2a; + else if (PointsEqual(prev->pt, pt2)) p4 = prev; + else if ((p3 == pp2a) || (p3 == prev)) + p4 = InsertPolyPtBetween(pp2a, prev, pt2); + else if (Pt3IsBetweenPt1AndPt2(pp2a->pt, p3->pt, pt2)) + p4 = InsertPolyPtBetween(pp2a, p3, pt2); else + p4 = InsertPolyPtBetween(p3, prev, pt2); + + //p1.pt == p3.pt and p2.pt == p4.pt so join p1 to p3 and p2 to p4 ... + if (p1->next == p2 && p3->prev == p4) + { + p1->next = p3; + p3->prev = p1; + p2->prev = p4; + p4->next = p2; + } + else if (p1->prev == p2 && p3->next == p4) + { + p1->prev = p3; + p3->next = p1; + p2->next = p4; + p4->prev = p2; + } + else + continue; //an orientation is probably wrong + + if (j->poly2Idx == j->poly1Idx) + { + //instead of joining two polygons, we've just created a new one by + //splitting one polygon into two. + outRec1->pts = GetBottomPt(p1); + outRec1->bottomPt = outRec1->pts; + outRec1->bottomPt->idx = outRec1->idx; + outRec2 = CreateOutRec(); + m_PolyOuts.push_back(outRec2); + outRec2->idx = (int)m_PolyOuts.size()-1; + j->poly2Idx = outRec2->idx; + outRec2->pts = GetBottomPt(p2); + outRec2->bottomPt = outRec2->pts; + outRec2->bottomPt->idx = outRec2->idx; + + if (PointInPolygon(outRec2->pts->pt, outRec1->pts, m_UseFullRange)) + { + //outRec2 is contained by outRec1 ... + outRec2->isHole = !outRec1->isHole; + outRec2->FirstLeft = outRec1; + if (outRec2->isHole == + (m_ReverseOutput ^ Orientation(outRec2, m_UseFullRange))) + ReversePolyPtLinks(*outRec2->pts); + } else if (PointInPolygon(outRec1->pts->pt, outRec2->pts, m_UseFullRange)) + { + //outRec1 is contained by outRec2 ... + outRec2->isHole = outRec1->isHole; + outRec1->isHole = !outRec2->isHole; + outRec2->FirstLeft = outRec1->FirstLeft; + outRec1->FirstLeft = outRec2; + if (outRec1->isHole == + (m_ReverseOutput ^ Orientation(outRec1, m_UseFullRange))) + ReversePolyPtLinks(*outRec1->pts); + //make sure any contained holes now link to the correct polygon ... + if (fixHoleLinkages) CheckHoleLinkages1(outRec1, outRec2); + } else + { + outRec2->isHole = outRec1->isHole; + outRec2->FirstLeft = outRec1->FirstLeft; + //make sure any contained holes now link to the correct polygon ... + if (fixHoleLinkages) CheckHoleLinkages1(outRec1, outRec2); + } + + //now fixup any subsequent joins that match this polygon + for (JoinList::size_type k = i+1; k < m_Joins.size(); k++) + { + JoinRec* j2 = m_Joins[k]; + if (j2->poly1Idx == j->poly1Idx && PointIsVertex(j2->pt1a, p2)) + j2->poly1Idx = j->poly2Idx; + if (j2->poly2Idx == j->poly1Idx && PointIsVertex(j2->pt2a, p2)) + j2->poly2Idx = j->poly2Idx; + } + + //now cleanup redundant edges too ... + FixupOutPolygon(*outRec1); + FixupOutPolygon(*outRec2); + + if (Orientation(outRec1, m_UseFullRange) != (Area(*outRec1, m_UseFullRange) > 0)) + DisposeBottomPt(*outRec1); + if (Orientation(outRec2, m_UseFullRange) != (Area(*outRec2, m_UseFullRange) > 0)) + DisposeBottomPt(*outRec2); + + } else + { + //joined 2 polygons together ... + + //make sure any holes contained by outRec2 now link to outRec1 ... + if (fixHoleLinkages) CheckHoleLinkages2(outRec1, outRec2); + + //now cleanup redundant edges too ... + FixupOutPolygon(*outRec1); + + if (outRec1->pts) + { + outRec1->isHole = !Orientation(outRec1, m_UseFullRange); + if (outRec1->isHole && !outRec1->FirstLeft) + outRec1->FirstLeft = outRec2->FirstLeft; + } + + //delete the obsolete pointer ... + int OKIdx = outRec1->idx; + int ObsoleteIdx = outRec2->idx; + outRec2->pts = 0; + outRec2->bottomPt = 0; + outRec2->AppendLink = outRec1; + + //now fixup any subsequent Joins that match this polygon + for (JoinList::size_type k = i+1; k < m_Joins.size(); k++) + { + JoinRec* j2 = m_Joins[k]; + if (j2->poly1Idx == ObsoleteIdx) j2->poly1Idx = OKIdx; + if (j2->poly2Idx == ObsoleteIdx) j2->poly2Idx = OKIdx; + } + } + } +} +//------------------------------------------------------------------------------ + +void ReversePolygon(Polygon& p) +{ + std::reverse(p.begin(), p.end()); +} +//------------------------------------------------------------------------------ + +void ReversePolygons(Polygons& p) +{ + for (Polygons::size_type i = 0; i < p.size(); ++i) + ReversePolygon(p[i]); +} + +//------------------------------------------------------------------------------ +// OffsetPolygon functions ... +//------------------------------------------------------------------------------ + +struct DoublePoint +{ + double X; + double Y; + DoublePoint(double x = 0, double y = 0) : X(x), Y(y) {} +}; +//------------------------------------------------------------------------------ + +Polygon BuildArc(const IntPoint &pt, + const double a1, const double a2, const double r) +{ + long64 steps = std::max(6, int(std::sqrt(std::fabs(r)) * std::fabs(a2 - a1))); + if (steps > 0x100000) steps = 0x100000; + int n = (unsigned)steps; + Polygon result(n); + double da = (a2 - a1) / (n -1); + double a = a1; + for (int i = 0; i < n; ++i) + { + result[i].X = pt.X + Round(std::cos(a)*r); + result[i].Y = pt.Y + Round(std::sin(a)*r); + a += da; + } + return result; +} +//------------------------------------------------------------------------------ + +DoublePoint GetUnitNormal( const IntPoint &pt1, const IntPoint &pt2) +{ + if(pt2.X == pt1.X && pt2.Y == pt1.Y) + return DoublePoint(0, 0); + + double dx = (double)(pt2.X - pt1.X); + double dy = (double)(pt2.Y - pt1.Y); + double f = 1 *1.0/ std::sqrt( dx*dx + dy*dy ); + dx *= f; + dy *= f; + return DoublePoint(dy, -dx); +} + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ + +class PolyOffsetBuilder +{ +private: + Polygons m_p; + Polygon* m_curr_poly; + std::vector normals; + double m_delta, m_RMin, m_R; + size_t m_i, m_j, m_k; + static const int buffLength = 128; + JoinType m_jointype; + +public: + +PolyOffsetBuilder(const Polygons& in_polys, Polygons& out_polys, + double delta, JoinType jointype, double MiterLimit) +{ + //nb precondition - out_polys != ptsin_polys + if (NEAR_ZERO(delta)) + { + out_polys = in_polys; + return; + } + + this->m_p = in_polys; + this->m_delta = delta; + this->m_jointype = jointype; + if (MiterLimit <= 1) MiterLimit = 1; + m_RMin = 2/(MiterLimit*MiterLimit); + + double deltaSq = delta*delta; + out_polys.clear(); + out_polys.resize(in_polys.size()); + for (m_i = 0; m_i < in_polys.size(); m_i++) + { + m_curr_poly = &out_polys[m_i]; + size_t len = in_polys[m_i].size(); + if (len > 1 && m_p[m_i][0].X == m_p[m_i][len - 1].X && + m_p[m_i][0].Y == m_p[m_i][len-1].Y) len--; + + //when 'shrinking' polygons - to minimize artefacts + //strip those polygons that have an area < pi * delta^2 ... + double a1 = Area(in_polys[m_i]); + if (delta < 0) { if (a1 > 0 && a1 < deltaSq *pi) len = 0; } + else if (a1 < 0 && -a1 < deltaSq *pi) len = 0; //holes have neg. area + + if (len == 0 || (len < 3 && delta <= 0)) + continue; + else if (len == 1) + { + Polygon arc; + arc = BuildArc(in_polys[m_i][len-1], 0, 2 * pi, delta); + out_polys[m_i] = arc; + continue; + } + + //build normals ... + normals.clear(); + normals.resize(len); + normals[len-1] = GetUnitNormal(in_polys[m_i][len-1], in_polys[m_i][0]); + for (m_j = 0; m_j < len -1; ++m_j) + normals[m_j] = GetUnitNormal(in_polys[m_i][m_j], in_polys[m_i][m_j+1]); + + m_k = len -1; + for (m_j = 0; m_j < len; ++m_j) + { + switch (jointype) + { + case jtMiter: + { + m_R = 1 + (normals[m_j].X*normals[m_k].X + + normals[m_j].Y*normals[m_k].Y); + if (m_R >= m_RMin) DoMiter(); else DoSquare(MiterLimit); + break; + } + case jtSquare: DoSquare(); break; + case jtRound: DoRound(); break; + } + m_k = m_j; + } + } + + //finally, clean up untidy corners using Clipper ... + Clipper clpr; + clpr.AddPolygons(out_polys, ptSubject); + if (delta > 0) + { + if (!clpr.Execute(ctUnion, out_polys, pftPositive, pftPositive)) + out_polys.clear(); + } + else + { + IntRect r = clpr.GetBounds(); + Polygon outer(4); + outer[0] = IntPoint(r.left - 10, r.bottom + 10); + outer[1] = IntPoint(r.right + 10, r.bottom + 10); + outer[2] = IntPoint(r.right + 10, r.top - 10); + outer[3] = IntPoint(r.left - 10, r.top - 10); + + clpr.AddPolygon(outer, ptSubject); + if (clpr.Execute(ctUnion, out_polys, pftNegative, pftNegative)) + { + out_polys.erase(out_polys.begin()); + ReversePolygons(out_polys); + + } else + out_polys.clear(); + } +} +//------------------------------------------------------------------------------ + +private: + +void AddPoint(const IntPoint& pt) +{ + Polygon::size_type len = m_curr_poly->size(); + if (len == m_curr_poly->capacity()) + m_curr_poly->reserve(len + buffLength); + m_curr_poly->push_back(pt); +} +//------------------------------------------------------------------------------ + +void DoSquare(double mul = 1.0) +{ + IntPoint pt1 = IntPoint((long64)Round(m_p[m_i][m_j].X + normals[m_k].X * m_delta), + (long64)Round(m_p[m_i][m_j].Y + normals[m_k].Y * m_delta)); + IntPoint pt2 = IntPoint((long64)Round(m_p[m_i][m_j].X + normals[m_j].X * m_delta), + (long64)Round(m_p[m_i][m_j].Y + normals[m_j].Y * m_delta)); + if ((normals[m_k].X * normals[m_j].Y - normals[m_j].X * normals[m_k].Y) * m_delta >= 0) + { + double a1 = std::atan2(normals[m_k].Y, normals[m_k].X); + double a2 = std::atan2(-normals[m_j].Y, -normals[m_j].X); + a1 = std::fabs(a2 - a1); + if (a1 > pi) a1 = pi * 2 - a1; + double dx = std::tan((pi - a1)/4) * std::fabs(m_delta * mul); + pt1 = IntPoint((long64)(pt1.X -normals[m_k].Y * dx), + (long64)(pt1.Y + normals[m_k].X * dx)); + AddPoint(pt1); + pt2 = IntPoint((long64)(pt2.X + normals[m_j].Y * dx), + (long64)(pt2.Y -normals[m_j].X * dx)); + AddPoint(pt2); + } + else + { + AddPoint(pt1); + AddPoint(m_p[m_i][m_j]); + AddPoint(pt2); + } +} +//------------------------------------------------------------------------------ + +void DoMiter() +{ + if ((normals[m_k].X * normals[m_j].Y - normals[m_j].X * normals[m_k].Y) * m_delta >= 0) + { + double q = m_delta / m_R; + AddPoint(IntPoint((long64)Round(m_p[m_i][m_j].X + + (normals[m_k].X + normals[m_j].X) * q), + (long64)Round(m_p[m_i][m_j].Y + (normals[m_k].Y + normals[m_j].Y) * q))); + } + else + { + IntPoint pt1 = IntPoint((long64)Round(m_p[m_i][m_j].X + normals[m_k].X * + m_delta), (long64)Round(m_p[m_i][m_j].Y + normals[m_k].Y * m_delta)); + IntPoint pt2 = IntPoint((long64)Round(m_p[m_i][m_j].X + normals[m_j].X * + m_delta), (long64)Round(m_p[m_i][m_j].Y + normals[m_j].Y * m_delta)); + AddPoint(pt1); + AddPoint(m_p[m_i][m_j]); + AddPoint(pt2); + } +} +//------------------------------------------------------------------------------ + +void DoRound() +{ + IntPoint pt1 = IntPoint((long64)Round(m_p[m_i][m_j].X + normals[m_k].X * m_delta), + (long64)Round(m_p[m_i][m_j].Y + normals[m_k].Y * m_delta)); + IntPoint pt2 = IntPoint((long64)Round(m_p[m_i][m_j].X + normals[m_j].X * m_delta), + (long64)Round(m_p[m_i][m_j].Y + normals[m_j].Y * m_delta)); + AddPoint(pt1); + //round off reflex angles (ie > 180 deg) unless almost flat (ie < ~10deg). + if ((normals[m_k].X*normals[m_j].Y - normals[m_j].X*normals[m_k].Y) * m_delta >= 0) + { + if (normals[m_j].X * normals[m_k].X + normals[m_j].Y * normals[m_k].Y < 0.985) + { + double a1 = std::atan2(normals[m_k].Y, normals[m_k].X); + double a2 = std::atan2(normals[m_j].Y, normals[m_j].X); + if (m_delta > 0 && a2 < a1) a2 += pi *2; + else if (m_delta < 0 && a2 > a1) a2 -= pi *2; + Polygon arc = BuildArc(m_p[m_i][m_j], a1, a2, m_delta); + for (Polygon::size_type m = 0; m < arc.size(); m++) + AddPoint(arc[m]); + } + } + else + AddPoint(m_p[m_i][m_j]); + AddPoint(pt2); +} +//-------------------------------------------------------------------------- + +}; //end PolyOffsetBuilder + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ + +void OffsetPolygons(const Polygons &in_polys, Polygons &out_polys, + double delta, JoinType jointype, double MiterLimit) +{ + if (&out_polys == &in_polys) + { + Polygons poly2(in_polys); + PolyOffsetBuilder(poly2, out_polys, delta, jointype, MiterLimit); + } + else PolyOffsetBuilder(in_polys, out_polys, delta, jointype, MiterLimit); +} +//------------------------------------------------------------------------------ + +void SimplifyPolygon(const Polygon &in_poly, Polygons &out_polys, PolyFillType fillType) +{ + Clipper c; + c.AddPolygon(in_poly, ptSubject); + c.Execute(ctUnion, out_polys, fillType, fillType); +} +//------------------------------------------------------------------------------ + +void SimplifyPolygons(const Polygons &in_polys, Polygons &out_polys, PolyFillType fillType) +{ + Clipper c; + c.AddPolygons(in_polys, ptSubject); + c.Execute(ctUnion, out_polys, fillType, fillType); +} +//------------------------------------------------------------------------------ + +void SimplifyPolygons(Polygons &polys, PolyFillType fillType) +{ + SimplifyPolygons(polys, polys, fillType); +} +//------------------------------------------------------------------------------ + +std::ostream& operator <<(std::ostream &s, IntPoint& p) +{ + s << p.X << ' ' << p.Y << "\n"; + return s; +} +//------------------------------------------------------------------------------ + +std::ostream& operator <<(std::ostream &s, Polygon &p) +{ + for (Polygon::size_type i = 0; i < p.size(); i++) + s << p[i]; + s << "\n"; + return s; +} +//------------------------------------------------------------------------------ + +std::ostream& operator <<(std::ostream &s, Polygons &p) +{ + for (Polygons::size_type i = 0; i < p.size(); i++) + s << p[i]; + s << "\n"; + return s; +} +//------------------------------------------------------------------------------ + +} //ClipperLib namespace diff --git a/contrib/clipper/clipper.hpp b/contrib/clipper/clipper.hpp index 7cbe898df..f6f196d0d 100644 --- a/contrib/clipper/clipper.hpp +++ b/contrib/clipper/clipper.hpp @@ -1,306 +1,306 @@ -/******************************************************************************* -* * -* Author : Angus Johnson * -* Version : 4.8.8 * -* Date : 30 August 2012 * -* Website : http://www.angusj.com * -* Copyright : Angus Johnson 2010-2012 * -* * -* License: * -* Use, modification & distribution is subject to Boost Software License Ver 1. * -* http://www.boost.org/LICENSE_1_0.txt * -* * -* Attributions: * -* The code in this library is an extension of Bala Vatti's clipping algorithm: * -* "A generic solution to polygon clipping" * -* Communications of the ACM, Vol 35, Issue 7 (July 1992) pp 56-63. * -* http://portal.acm.org/citation.cfm?id=129906 * -* * -* Computer graphics and geometric modeling: implementation and algorithms * -* By Max K. Agoston * -* Springer; 1 edition (January 4, 2005) * -* http://books.google.com/books?q=vatti+clipping+agoston * -* * -* See also: * -* "Polygon Offsetting by Computing Winding Numbers" * -* Paper no. DETC2005-85513 pp. 565-575 * -* ASME 2005 International Design Engineering Technical Conferences * -* and Computers and Information in Engineering Conference (IDETC/CIE2005) * -* September 24–28, 2005 , Long Beach, California, USA * -* http://www.me.berkeley.edu/~mcmains/pubs/DAC05OffsetPolygon.pdf * -* * -*******************************************************************************/ - -#ifndef clipper_hpp -#define clipper_hpp - -#include -#include -#include -#include -#include - -namespace ClipperLib { - -enum ClipType { ctIntersection, ctUnion, ctDifference, ctXor }; -enum PolyType { ptSubject, ptClip }; -//By far the most widely used winding rules for polygon filling are -//EvenOdd & NonZero (GDI, GDI+, XLib, OpenGL, Cairo, AGG, Quartz, SVG, Gr32) -//Others rules include Positive, Negative and ABS_GTR_EQ_TWO (only in OpenGL) -//see http://glprogramming.com/red/chapter11.html -enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative }; - -typedef signed long long long64; -typedef unsigned long long ulong64; - -struct IntPoint { -public: - long64 X; - long64 Y; - IntPoint(long64 x = 0, long64 y = 0): X(x), Y(y) {}; - friend std::ostream& operator <<(std::ostream &s, IntPoint &p); -}; - -typedef std::vector< IntPoint > Polygon; -typedef std::vector< Polygon > Polygons; - -std::ostream& operator <<(std::ostream &s, Polygon &p); -std::ostream& operator <<(std::ostream &s, Polygons &p); - -struct ExPolygon { - Polygon outer; - Polygons holes; -}; -typedef std::vector< ExPolygon > ExPolygons; - -enum JoinType { jtSquare, jtRound, jtMiter }; - -bool Orientation(const Polygon &poly); -double Area(const Polygon &poly); -void OffsetPolygons(const Polygons &in_polys, Polygons &out_polys, - double delta, JoinType jointype = jtSquare, double MiterLimit = 2); -void SimplifyPolygon(const Polygon &in_poly, Polygons &out_polys, PolyFillType fillType = pftEvenOdd); -void SimplifyPolygons(const Polygons &in_polys, Polygons &out_polys, PolyFillType fillType = pftEvenOdd); -void SimplifyPolygons(Polygons &polys, PolyFillType fillType = pftEvenOdd); - -void ReversePolygon(Polygon& p); -void ReversePolygons(Polygons& p); - -//used internally ... -enum EdgeSide { esNeither = 0, esLeft = 1, esRight = 2, esBoth = 3 }; -enum IntersectProtects { ipNone = 0, ipLeft = 1, ipRight = 2, ipBoth = 3 }; - -struct TEdge { - long64 xbot; - long64 ybot; - long64 xcurr; - long64 ycurr; - long64 xtop; - long64 ytop; - double dx; - long64 tmpX; - PolyType polyType; - EdgeSide side; - int windDelta; //1 or -1 depending on winding direction - int windCnt; - int windCnt2; //winding count of the opposite polytype - int outIdx; - TEdge *next; - TEdge *prev; - TEdge *nextInLML; - TEdge *nextInAEL; - TEdge *prevInAEL; - TEdge *nextInSEL; - TEdge *prevInSEL; -}; - -struct IntersectNode { - TEdge *edge1; - TEdge *edge2; - IntPoint pt; - IntersectNode *next; -}; - -struct LocalMinima { - long64 Y; - TEdge *leftBound; - TEdge *rightBound; - LocalMinima *next; -}; - -struct Scanbeam { - long64 Y; - Scanbeam *next; -}; - -struct OutPt; //forward declaration - -struct OutRec { - int idx; - bool isHole; - OutRec *FirstLeft; - OutRec *AppendLink; - OutPt *pts; - OutPt *bottomPt; - OutPt *bottomFlag; - EdgeSide sides; -}; - -struct OutPt { - int idx; - IntPoint pt; - OutPt *next; - OutPt *prev; -}; - -struct JoinRec { - IntPoint pt1a; - IntPoint pt1b; - int poly1Idx; - IntPoint pt2a; - IntPoint pt2b; - int poly2Idx; -}; - -struct HorzJoinRec { - TEdge *edge; - int savedIdx; -}; - -struct IntRect { long64 left; long64 top; long64 right; long64 bottom; }; - -typedef std::vector < OutRec* > PolyOutList; -typedef std::vector < TEdge* > EdgeList; -typedef std::vector < JoinRec* > JoinList; -typedef std::vector < HorzJoinRec* > HorzJoinList; - -//ClipperBase is the ancestor to the Clipper class. It should not be -//instantiated directly. This class simply abstracts the conversion of sets of -//polygon coordinates into edge objects that are stored in a LocalMinima list. -class ClipperBase -{ -public: - ClipperBase(); - virtual ~ClipperBase(); - bool AddPolygon(const Polygon &pg, PolyType polyType); - bool AddPolygons( const Polygons &ppg, PolyType polyType); - virtual void Clear(); - IntRect GetBounds(); -protected: - void DisposeLocalMinimaList(); - TEdge* AddBoundsToLML(TEdge *e); - void PopLocalMinima(); - virtual void Reset(); - void InsertLocalMinima(LocalMinima *newLm); - LocalMinima *m_CurrentLM; - LocalMinima *m_MinimaList; - bool m_UseFullRange; - EdgeList m_edges; -}; - -class Clipper : public virtual ClipperBase -{ -public: - Clipper(); - ~Clipper(); - bool Execute(ClipType clipType, - Polygons &solution, - PolyFillType subjFillType = pftEvenOdd, - PolyFillType clipFillType = pftEvenOdd); - bool Execute(ClipType clipType, - ExPolygons &solution, - PolyFillType subjFillType = pftEvenOdd, - PolyFillType clipFillType = pftEvenOdd); - void Clear(); - bool ReverseSolution() {return m_ReverseOutput;}; - void ReverseSolution(bool value) {m_ReverseOutput = value;}; -protected: - void Reset(); - virtual bool ExecuteInternal(bool fixHoleLinkages); -private: - PolyOutList m_PolyOuts; - JoinList m_Joins; - HorzJoinList m_HorizJoins; - ClipType m_ClipType; - Scanbeam *m_Scanbeam; - TEdge *m_ActiveEdges; - TEdge *m_SortedEdges; - IntersectNode *m_IntersectNodes; - bool m_ExecuteLocked; - PolyFillType m_ClipFillType; - PolyFillType m_SubjFillType; - bool m_ReverseOutput; - void DisposeScanbeamList(); - void SetWindingCount(TEdge& edge); - bool IsEvenOddFillType(const TEdge& edge) const; - bool IsEvenOddAltFillType(const TEdge& edge) const; - void InsertScanbeam(const long64 Y); - long64 PopScanbeam(); - void InsertLocalMinimaIntoAEL(const long64 botY); - void InsertEdgeIntoAEL(TEdge *edge); - void AddEdgeToSEL(TEdge *edge); - void CopyAELToSEL(); - void DeleteFromSEL(TEdge *e); - void DeleteFromAEL(TEdge *e); - void UpdateEdgeIntoAEL(TEdge *&e); - void SwapPositionsInSEL(TEdge *edge1, TEdge *edge2); - bool IsContributing(const TEdge& edge) const; - bool IsTopHorz(const long64 XPos); - void SwapPositionsInAEL(TEdge *edge1, TEdge *edge2); - void DoMaxima(TEdge *e, long64 topY); - void ProcessHorizontals(); - void ProcessHorizontal(TEdge *horzEdge); - void AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &pt); - void AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &pt); - void AppendPolygon(TEdge *e1, TEdge *e2); - void DoEdge1(TEdge *edge1, TEdge *edge2, const IntPoint &pt); - void DoEdge2(TEdge *edge1, TEdge *edge2, const IntPoint &pt); - void DoBothEdges(TEdge *edge1, TEdge *edge2, const IntPoint &pt); - void IntersectEdges(TEdge *e1, TEdge *e2, - const IntPoint &pt, IntersectProtects protects); - OutRec* CreateOutRec(); - void AddOutPt(TEdge *e, const IntPoint &pt); - void DisposeBottomPt(OutRec &outRec); - void DisposeAllPolyPts(); - void DisposeOutRec(PolyOutList::size_type index); - bool ProcessIntersections(const long64 botY, const long64 topY); - void AddIntersectNode(TEdge *e1, TEdge *e2, const IntPoint &pt); - void BuildIntersectList(const long64 botY, const long64 topY); - void ProcessIntersectList(); - void ProcessEdgesAtTopOfScanbeam(const long64 topY); - void BuildResult(Polygons& polys); - void BuildResultEx(ExPolygons& polys); - void SetHoleState(TEdge *e, OutRec *OutRec); - void DisposeIntersectNodes(); - bool FixupIntersections(); - void FixupOutPolygon(OutRec &outRec); - bool IsHole(TEdge *e); - void FixHoleLinkage(OutRec *outRec); - void CheckHoleLinkages1(OutRec *outRec1, OutRec *outRec2); - void CheckHoleLinkages2(OutRec *outRec1, OutRec *outRec2); - void AddJoin(TEdge *e1, TEdge *e2, int e1OutIdx = -1, int e2OutIdx = -1); - void ClearJoins(); - void AddHorzJoin(TEdge *e, int idx); - void ClearHorzJoins(); - void JoinCommonEdges(bool fixHoleLinkages); -}; - -//------------------------------------------------------------------------------ -//------------------------------------------------------------------------------ - -class clipperException : public std::exception -{ - public: - clipperException(const char* description): m_descr(description) {} - virtual ~clipperException() throw() {} - virtual const char* what() const throw() {return m_descr.c_str();} - private: - std::string m_descr; -}; -//------------------------------------------------------------------------------ - -} //ClipperLib namespace - -#endif //clipper_hpp - - +/******************************************************************************* +* * +* Author : Angus Johnson * +* Version : 4.8.8 * +* Date : 30 August 2012 * +* Website : http://www.angusj.com * +* Copyright : Angus Johnson 2010-2012 * +* * +* License: * +* Use, modification & distribution is subject to Boost Software License Ver 1. * +* http://www.boost.org/LICENSE_1_0.txt * +* * +* Attributions: * +* The code in this library is an extension of Bala Vatti's clipping algorithm: * +* "A generic solution to polygon clipping" * +* Communications of the ACM, Vol 35, Issue 7 (July 1992) pp 56-63. * +* http://portal.acm.org/citation.cfm?id=129906 * +* * +* Computer graphics and geometric modeling: implementation and algorithms * +* By Max K. Agoston * +* Springer; 1 edition (January 4, 2005) * +* http://books.google.com/books?q=vatti+clipping+agoston * +* * +* See also: * +* "Polygon Offsetting by Computing Winding Numbers" * +* Paper no. DETC2005-85513 pp. 565-575 * +* ASME 2005 International Design Engineering Technical Conferences * +* and Computers and Information in Engineering Conference (IDETC/CIE2005) * +* September 24–28, 2005 , Long Beach, California, USA * +* http://www.me.berkeley.edu/~mcmains/pubs/DAC05OffsetPolygon.pdf * +* * +*******************************************************************************/ + +#ifndef clipper_hpp +#define clipper_hpp + +#include +#include +#include +#include +#include + +namespace ClipperLib { + +enum ClipType { ctIntersection, ctUnion, ctDifference, ctXor }; +enum PolyType { ptSubject, ptClip }; +//By far the most widely used winding rules for polygon filling are +//EvenOdd & NonZero (GDI, GDI+, XLib, OpenGL, Cairo, AGG, Quartz, SVG, Gr32) +//Others rules include Positive, Negative and ABS_GTR_EQ_TWO (only in OpenGL) +//see http://glprogramming.com/red/chapter11.html +enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative }; + +typedef signed long long long64; +typedef unsigned long long ulong64; + +struct IntPoint { +public: + long64 X; + long64 Y; + IntPoint(long64 x = 0, long64 y = 0): X(x), Y(y) {}; + friend std::ostream& operator <<(std::ostream &s, IntPoint &p); +}; + +typedef std::vector< IntPoint > Polygon; +typedef std::vector< Polygon > Polygons; + +std::ostream& operator <<(std::ostream &s, Polygon &p); +std::ostream& operator <<(std::ostream &s, Polygons &p); + +struct ExPolygon { + Polygon outer; + Polygons holes; +}; +typedef std::vector< ExPolygon > ExPolygons; + +enum JoinType { jtSquare, jtRound, jtMiter }; + +bool Orientation(const Polygon &poly); +double Area(const Polygon &poly); +void OffsetPolygons(const Polygons &in_polys, Polygons &out_polys, + double delta, JoinType jointype = jtSquare, double MiterLimit = 2); +void SimplifyPolygon(const Polygon &in_poly, Polygons &out_polys, PolyFillType fillType = pftEvenOdd); +void SimplifyPolygons(const Polygons &in_polys, Polygons &out_polys, PolyFillType fillType = pftEvenOdd); +void SimplifyPolygons(Polygons &polys, PolyFillType fillType = pftEvenOdd); + +void ReversePolygon(Polygon& p); +void ReversePolygons(Polygons& p); + +//used internally ... +enum EdgeSide { esNeither = 0, esLeft = 1, esRight = 2, esBoth = 3 }; +enum IntersectProtects { ipNone = 0, ipLeft = 1, ipRight = 2, ipBoth = 3 }; + +struct TEdge { + long64 xbot; + long64 ybot; + long64 xcurr; + long64 ycurr; + long64 xtop; + long64 ytop; + double dx; + long64 tmpX; + PolyType polyType; + EdgeSide side; + int windDelta; //1 or -1 depending on winding direction + int windCnt; + int windCnt2; //winding count of the opposite polytype + int outIdx; + TEdge *next; + TEdge *prev; + TEdge *nextInLML; + TEdge *nextInAEL; + TEdge *prevInAEL; + TEdge *nextInSEL; + TEdge *prevInSEL; +}; + +struct IntersectNode { + TEdge *edge1; + TEdge *edge2; + IntPoint pt; + IntersectNode *next; +}; + +struct LocalMinima { + long64 Y; + TEdge *leftBound; + TEdge *rightBound; + LocalMinima *next; +}; + +struct Scanbeam { + long64 Y; + Scanbeam *next; +}; + +struct OutPt; //forward declaration + +struct OutRec { + int idx; + bool isHole; + OutRec *FirstLeft; + OutRec *AppendLink; + OutPt *pts; + OutPt *bottomPt; + OutPt *bottomFlag; + EdgeSide sides; +}; + +struct OutPt { + int idx; + IntPoint pt; + OutPt *next; + OutPt *prev; +}; + +struct JoinRec { + IntPoint pt1a; + IntPoint pt1b; + int poly1Idx; + IntPoint pt2a; + IntPoint pt2b; + int poly2Idx; +}; + +struct HorzJoinRec { + TEdge *edge; + int savedIdx; +}; + +struct IntRect { long64 left; long64 top; long64 right; long64 bottom; }; + +typedef std::vector < OutRec* > PolyOutList; +typedef std::vector < TEdge* > EdgeList; +typedef std::vector < JoinRec* > JoinList; +typedef std::vector < HorzJoinRec* > HorzJoinList; + +//ClipperBase is the ancestor to the Clipper class. It should not be +//instantiated directly. This class simply abstracts the conversion of sets of +//polygon coordinates into edge objects that are stored in a LocalMinima list. +class ClipperBase +{ +public: + ClipperBase(); + virtual ~ClipperBase(); + bool AddPolygon(const Polygon &pg, PolyType polyType); + bool AddPolygons( const Polygons &ppg, PolyType polyType); + virtual void Clear(); + IntRect GetBounds(); +protected: + void DisposeLocalMinimaList(); + TEdge* AddBoundsToLML(TEdge *e); + void PopLocalMinima(); + virtual void Reset(); + void InsertLocalMinima(LocalMinima *newLm); + LocalMinima *m_CurrentLM; + LocalMinima *m_MinimaList; + bool m_UseFullRange; + EdgeList m_edges; +}; + +class Clipper : public virtual ClipperBase +{ +public: + Clipper(); + ~Clipper(); + bool Execute(ClipType clipType, + Polygons &solution, + PolyFillType subjFillType = pftEvenOdd, + PolyFillType clipFillType = pftEvenOdd); + bool Execute(ClipType clipType, + ExPolygons &solution, + PolyFillType subjFillType = pftEvenOdd, + PolyFillType clipFillType = pftEvenOdd); + void Clear(); + bool ReverseSolution() {return m_ReverseOutput;}; + void ReverseSolution(bool value) {m_ReverseOutput = value;}; +protected: + void Reset(); + virtual bool ExecuteInternal(bool fixHoleLinkages); +private: + PolyOutList m_PolyOuts; + JoinList m_Joins; + HorzJoinList m_HorizJoins; + ClipType m_ClipType; + Scanbeam *m_Scanbeam; + TEdge *m_ActiveEdges; + TEdge *m_SortedEdges; + IntersectNode *m_IntersectNodes; + bool m_ExecuteLocked; + PolyFillType m_ClipFillType; + PolyFillType m_SubjFillType; + bool m_ReverseOutput; + void DisposeScanbeamList(); + void SetWindingCount(TEdge& edge); + bool IsEvenOddFillType(const TEdge& edge) const; + bool IsEvenOddAltFillType(const TEdge& edge) const; + void InsertScanbeam(const long64 Y); + long64 PopScanbeam(); + void InsertLocalMinimaIntoAEL(const long64 botY); + void InsertEdgeIntoAEL(TEdge *edge); + void AddEdgeToSEL(TEdge *edge); + void CopyAELToSEL(); + void DeleteFromSEL(TEdge *e); + void DeleteFromAEL(TEdge *e); + void UpdateEdgeIntoAEL(TEdge *&e); + void SwapPositionsInSEL(TEdge *edge1, TEdge *edge2); + bool IsContributing(const TEdge& edge) const; + bool IsTopHorz(const long64 XPos); + void SwapPositionsInAEL(TEdge *edge1, TEdge *edge2); + void DoMaxima(TEdge *e, long64 topY); + void ProcessHorizontals(); + void ProcessHorizontal(TEdge *horzEdge); + void AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &pt); + void AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &pt); + void AppendPolygon(TEdge *e1, TEdge *e2); + void DoEdge1(TEdge *edge1, TEdge *edge2, const IntPoint &pt); + void DoEdge2(TEdge *edge1, TEdge *edge2, const IntPoint &pt); + void DoBothEdges(TEdge *edge1, TEdge *edge2, const IntPoint &pt); + void IntersectEdges(TEdge *e1, TEdge *e2, + const IntPoint &pt, IntersectProtects protects); + OutRec* CreateOutRec(); + void AddOutPt(TEdge *e, const IntPoint &pt); + void DisposeBottomPt(OutRec &outRec); + void DisposeAllPolyPts(); + void DisposeOutRec(PolyOutList::size_type index); + bool ProcessIntersections(const long64 botY, const long64 topY); + void AddIntersectNode(TEdge *e1, TEdge *e2, const IntPoint &pt); + void BuildIntersectList(const long64 botY, const long64 topY); + void ProcessIntersectList(); + void ProcessEdgesAtTopOfScanbeam(const long64 topY); + void BuildResult(Polygons& polys); + void BuildResultEx(ExPolygons& polys); + void SetHoleState(TEdge *e, OutRec *OutRec); + void DisposeIntersectNodes(); + bool FixupIntersections(); + void FixupOutPolygon(OutRec &outRec); + bool IsHole(TEdge *e); + void FixHoleLinkage(OutRec *outRec); + void CheckHoleLinkages1(OutRec *outRec1, OutRec *outRec2); + void CheckHoleLinkages2(OutRec *outRec1, OutRec *outRec2); + void AddJoin(TEdge *e1, TEdge *e2, int e1OutIdx = -1, int e2OutIdx = -1); + void ClearJoins(); + void AddHorzJoin(TEdge *e, int idx); + void ClearHorzJoins(); + void JoinCommonEdges(bool fixHoleLinkages); +}; + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ + +class clipperException : public std::exception +{ + public: + clipperException(const char* description): m_descr(description) {} + virtual ~clipperException() throw() {} + virtual const char* what() const throw() {return m_descr.c_str();} + private: + std::string m_descr; +}; +//------------------------------------------------------------------------------ + +} //ClipperLib namespace + +#endif //clipper_hpp + + diff --git a/contrib/irrXML/CXMLReaderImpl.h b/contrib/irrXML/CXMLReaderImpl.h index d2472b28b..63b700dc1 100644 --- a/contrib/irrXML/CXMLReaderImpl.h +++ b/contrib/irrXML/CXMLReaderImpl.h @@ -1,809 +1,809 @@ -// Copyright (C) 2002-2005 Nikolaus Gebhardt -// This file is part of the "Irrlicht Engine" and the "irrXML" project. -// For conditions of distribution and use, see copyright notice in irrlicht.h and/or irrXML.h - -#ifndef __ICXML_READER_IMPL_H_INCLUDED__ -#define __ICXML_READER_IMPL_H_INCLUDED__ - -#include "irrXML.h" -#include "irrString.h" -#include "irrArray.h" - -using namespace Assimp; - -#ifdef _DEBUG -#define IRR_DEBUGPRINT(x) printf((x)); -#else // _DEBUG -#define IRR_DEBUGPRINT(x) -#endif // _DEBUG - - -namespace irr -{ -namespace io -{ - - -//! implementation of the IrrXMLReader -template -class CXMLReaderImpl : public IIrrXMLReader -{ -public: - - //! Constructor - CXMLReaderImpl(IFileReadCallBack* callback, bool deleteCallBack = true) - : TextData(0), P(0), TextBegin(0), TextSize(0), CurrentNodeType(EXN_NONE), - SourceFormat(ETF_ASCII), TargetFormat(ETF_ASCII) - { - if (!callback) - return; - - storeTargetFormat(); - - // read whole xml file - - readFile(callback); - - // clean up - - if (deleteCallBack) - delete callback; - - // create list with special characters - - createSpecialCharacterList(); - - // set pointer to text begin - P = TextBegin; - } - - - //! Destructor - virtual ~CXMLReaderImpl() - { - delete [] TextData; - } - - - //! Reads forward to the next xml node. - //! \return Returns false, if there was no further node. - virtual bool read() - { - // if not end reached, parse the node - if (P && (unsigned int)(P - TextBegin) < TextSize - 1 && *P != 0) - { - parseCurrentNode(); - return true; - } - - _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; - return false; - } - - - //! Returns the type of the current XML node. - virtual EXML_NODE getNodeType() const - { - return CurrentNodeType; - } - - - //! Returns attribute count of the current XML node. - virtual int getAttributeCount() const - { - return Attributes.size(); - } - - - //! Returns name of an attribute. - virtual const char_type* getAttributeName(int idx) const - { - if (idx < 0 || idx >= (int)Attributes.size()) - return 0; - - return Attributes[idx].Name.c_str(); - } - - - //! Returns the value of an attribute. - virtual const char_type* getAttributeValue(int idx) const - { - if (idx < 0 || idx >= (int)Attributes.size()) - return 0; - - return Attributes[idx].Value.c_str(); - } - - - //! Returns the value of an attribute. - virtual const char_type* getAttributeValue(const char_type* name) const - { - const SAttribute* attr = getAttributeByName(name); - if (!attr) - return 0; - - return attr->Value.c_str(); - } - - - //! Returns the value of an attribute - virtual const char_type* getAttributeValueSafe(const char_type* name) const - { - const SAttribute* attr = getAttributeByName(name); - if (!attr) - return EmptyString.c_str(); - - return attr->Value.c_str(); - } - - - - //! Returns the value of an attribute as integer. - int getAttributeValueAsInt(const char_type* name) const - { - return (int)getAttributeValueAsFloat(name); - } - - - //! Returns the value of an attribute as integer. - int getAttributeValueAsInt(int idx) const - { - return (int)getAttributeValueAsFloat(idx); - } - - - //! Returns the value of an attribute as float. - float getAttributeValueAsFloat(const char_type* name) const - { - const SAttribute* attr = getAttributeByName(name); - if (!attr) - return 0; - - core::stringc c = attr->Value.c_str(); - return fast_atof(c.c_str()); - } - - - //! Returns the value of an attribute as float. - float getAttributeValueAsFloat(int idx) const - { - const char_type* attrvalue = getAttributeValue(idx); - if (!attrvalue) - return 0; - - core::stringc c = attrvalue; - return fast_atof(c.c_str()); - } - - - //! Returns the name of the current node. - virtual const char_type* getNodeName() const - { - return NodeName.c_str(); - } - - - //! Returns data of the current node. - virtual const char_type* getNodeData() const - { - return NodeName.c_str(); - } - - - //! Returns if an element is an empty element, like - virtual bool isEmptyElement() const - { - return IsEmptyElement; - } - - //! Returns format of the source xml file. - virtual ETEXT_FORMAT getSourceFormat() const - { - return SourceFormat; - } - - //! Returns format of the strings returned by the parser. - virtual ETEXT_FORMAT getParserFormat() const - { - return TargetFormat; - } - -private: - - // Reads the current xml node - void parseCurrentNode() - { - char_type* start = P; - - // move forward until '<' found - while(*P != L'<' && *P) - ++P; - - if (!*P) - return; - - if (P - start > 0) - { - // we found some text, store it - if (setText(start, P)) - return; - } - - ++P; - - // based on current token, parse and report next element - switch(*P) - { - case L'/': - parseClosingXMLElement(); - break; - case L'?': - ignoreDefinition(); - break; - case L'!': - if (!parseCDATA()) - parseComment(); - break; - default: - parseOpeningXMLElement(); - break; - } - } - - - //! sets the state that text was found. Returns true if set should be set - bool setText(char_type* start, char_type* end) - { - // check if text is more than 2 characters, and if not, check if there is - // only white space, so that this text won't be reported - if (end - start < 3) - { - char_type* p = start; - for(; p != end; ++p) - if (!isWhiteSpace(*p)) - break; - - if (p == end) - return false; - } - - // set current text to the parsed text, and replace xml special characters - core::string s(start, (int)(end - start)); - NodeName = replaceSpecialCharacters(s); - - // current XML node type is text - CurrentNodeType = EXN_TEXT; - - return true; - } - - - - //! ignores an xml definition like - void ignoreDefinition() - { - CurrentNodeType = EXN_UNKNOWN; - - // move until end marked with '>' reached - while(*P != L'>') - ++P; - - ++P; - } - - - //! parses a comment - void parseComment() - { - CurrentNodeType = EXN_COMMENT; - P += 1; - - char_type *pCommentBegin = P; - - int count = 1; - - // move until end of comment reached - while(count) - { - if (*P == L'>') - --count; - else - if (*P == L'<') - ++count; - - ++P; - } - - P -= 3; - NodeName = core::string(pCommentBegin+2, (int)(P - pCommentBegin-2)); - P += 3; - } - - - //! parses an opening xml element and reads attributes - void parseOpeningXMLElement() - { - CurrentNodeType = EXN_ELEMENT; - IsEmptyElement = false; - Attributes.clear(); - - // find name - const char_type* startName = P; - - // find end of element - while(*P != L'>' && !isWhiteSpace(*P)) - ++P; - - const char_type* endName = P; - - // find Attributes - while(*P != L'>') - { - if (isWhiteSpace(*P)) - ++P; - else - { - if (*P != L'/') - { - // we've got an attribute - - // read the attribute names - const char_type* attributeNameBegin = P; - - while(!isWhiteSpace(*P) && *P != L'=') - ++P; - - const char_type* attributeNameEnd = P; - ++P; - - // read the attribute value - // check for quotes and single quotes, thx to murphy - while( (*P != L'\"') && (*P != L'\'') && *P) - ++P; - - if (!*P) // malformatted xml file - return; - - const char_type attributeQuoteChar = *P; - - ++P; - const char_type* attributeValueBegin = P; - - while(*P != attributeQuoteChar && *P) - ++P; - - if (!*P) // malformatted xml file - return; - - const char_type* attributeValueEnd = P; - ++P; - - SAttribute attr; - attr.Name = core::string(attributeNameBegin, - (int)(attributeNameEnd - attributeNameBegin)); - - core::string s(attributeValueBegin, - (int)(attributeValueEnd - attributeValueBegin)); - - attr.Value = replaceSpecialCharacters(s); - Attributes.push_back(attr); - } - else - { - // tag is closed directly - ++P; - IsEmptyElement = true; - break; - } - } - } - - // check if this tag is closing directly - if (endName > startName && *(endName-1) == L'/') - { - // directly closing tag - IsEmptyElement = true; - endName--; - } - - NodeName = core::string(startName, (int)(endName - startName)); - - ++P; - } - - - //! parses an closing xml tag - void parseClosingXMLElement() - { - CurrentNodeType = EXN_ELEMENT_END; - IsEmptyElement = false; - Attributes.clear(); - - ++P; - const char_type* pBeginClose = P; - - while(*P != L'>') - ++P; - - // remove trailing whitespace, if any - while( isspace( P[-1])) - --P; - - NodeName = core::string(pBeginClose, (int)(P - pBeginClose)); - ++P; - } - - //! parses a possible CDATA section, returns false if begin was not a CDATA section - bool parseCDATA() - { - if (*(P+1) != L'[') - return false; - - CurrentNodeType = EXN_CDATA; - - // skip '' && - (*(P-1) == L']') && - (*(P-2) == L']')) - { - cDataEnd = P - 2; - } - - ++P; - } - - if ( cDataEnd ) - NodeName = core::string(cDataBegin, (int)(cDataEnd - cDataBegin)); - else - NodeName = ""; - - return true; - } - - - // structure for storing attribute-name pairs - struct SAttribute - { - core::string Name; - core::string Value; - }; - - // finds a current attribute by name, returns 0 if not found - const SAttribute* getAttributeByName(const char_type* name) const - { - if (!name) - return 0; - - core::string n = name; - - for (int i=0; i<(int)Attributes.size(); ++i) - if (Attributes[i].Name == n) - return &Attributes[i]; - - return 0; - } - - // replaces xml special characters in a string and creates a new one - core::string replaceSpecialCharacters( - core::string& origstr) - { - int pos = origstr.findFirst(L'&'); - int oldPos = 0; - - if (pos == -1) - return origstr; - - core::string newstr; - - while(pos != -1 && pos < origstr.size()-2) - { - // check if it is one of the special characters - - int specialChar = -1; - for (int i=0; i<(int)SpecialCharacters.size(); ++i) - { - const char_type* p = &origstr.c_str()[pos]+1; - - if (equalsn(&SpecialCharacters[i][1], p, SpecialCharacters[i].size()-1)) - { - specialChar = i; - break; - } - } - - if (specialChar != -1) - { - newstr.append(origstr.subString(oldPos, pos - oldPos)); - newstr.append(SpecialCharacters[specialChar][0]); - pos += SpecialCharacters[specialChar].size(); - } - else - { - newstr.append(origstr.subString(oldPos, pos - oldPos + 1)); - pos += 1; - } - - // find next & - oldPos = pos; - pos = origstr.findNext(L'&', pos); - } - - if (oldPos < origstr.size()-1) - newstr.append(origstr.subString(oldPos, origstr.size()-oldPos)); - - return newstr; - } - - - - //! reads the xml file and converts it into the wanted character format. - bool readFile(IFileReadCallBack* callback) - { - int size = callback->getSize(); - size += 4; // We need two terminating 0's at the end. - // For ASCII we need 1 0's, for UTF-16 2, for UTF-32 4. - - char* data8 = new char[size]; - - if (!callback->read(data8, size-4)) - { - delete [] data8; - return false; - } - - // add zeros at end - - data8[size-1] = 0; - data8[size-2] = 0; - data8[size-3] = 0; - data8[size-4] = 0; - - char16* data16 = reinterpret_cast(data8); - char32* data32 = reinterpret_cast(data8); - - // now we need to convert the data to the desired target format - // based on the byte order mark. - - const unsigned char UTF8[] = {0xEF, 0xBB, 0xBF}; // 0xEFBBBF; - const int UTF16_BE = 0xFFFE; - const int UTF16_LE = 0xFEFF; - const int UTF32_BE = 0xFFFE0000; - const int UTF32_LE = 0x0000FEFF; - - // check source for all utf versions and convert to target data format - - if (size >= 4 && data32[0] == (char32)UTF32_BE) - { - // UTF-32, big endian - SourceFormat = ETF_UTF32_BE; - convertTextData(data32+1, data8, (size/4)); // data32+1 because we need to skip the header - } - else - if (size >= 4 && data32[0] == (char32)UTF32_LE) - { - // UTF-32, little endian - SourceFormat = ETF_UTF32_LE; - convertTextData(data32+1, data8, (size/4)); // data32+1 because we need to skip the header - } - else - if (size >= 2 && data16[0] == UTF16_BE) - { - // UTF-16, big endian - SourceFormat = ETF_UTF16_BE; - convertTextData(data16+1, data8, (size/2)); // data16+1 because we need to skip the header - } - else - if (size >= 2 && data16[0] == UTF16_LE) - { - // UTF-16, little endian - SourceFormat = ETF_UTF16_LE; - convertTextData(data16+1, data8, (size/2)); // data16+1 because we need to skip the header - } - else - if (size >= 3 && data8[0] == UTF8[0] && data8[1] == UTF8[1] && data8[2] == UTF8[2]) - { - // UTF-8 - SourceFormat = ETF_UTF8; - convertTextData(data8+3, data8, size); // data8+3 because we need to skip the header - } - else - { - // ASCII - SourceFormat = ETF_ASCII; - convertTextData(data8, data8, size); - } - - return true; - } - - - //! converts the text file into the desired format. - //! \param source: begin of the text (without byte order mark) - //! \param pointerToStore: pointer to text data block which can be - //! stored or deleted based on the nesessary conversion. - //! \param sizeWithoutHeader: Text size in characters without header - template - void convertTextData(src_char_type* source, char* pointerToStore, int sizeWithoutHeader) - { - // convert little to big endian if necessary - if (sizeof(src_char_type) > 1 && - isLittleEndian(TargetFormat) != isLittleEndian(SourceFormat)) - convertToLittleEndian(source); - - // check if conversion is necessary: - if (sizeof(src_char_type) == sizeof(char_type)) - { - // no need to convert - TextBegin = (char_type*)source; - TextData = (char_type*)pointerToStore; - TextSize = sizeWithoutHeader; - } - else - { - // convert source into target data format. - // TODO: implement a real conversion. This one just - // copies bytes. This is a problem when there are - // unicode symbols using more than one character. - - TextData = new char_type[sizeWithoutHeader]; - - // MSVC debugger complains here about loss of data ... - - - // FIXME - gcc complains about 'shift width larger than width of type' - // for T == unsigned long. Avoid it by messing around volatile .. - volatile unsigned int c = 3; - const src_char_type cc = (src_char_type)((((uint64_t)1u << (sizeof( char_type)< - void convertToLittleEndian(src_char_type* t) - { - if (sizeof(src_char_type) == 4) - { - // 32 bit - - while(*t) - { - *t = ((*t & 0xff000000) >> 24) | - ((*t & 0x00ff0000) >> 8) | - ((*t & 0x0000ff00) << 8) | - ((*t & 0x000000ff) << 24); - ++t; - } - } - else - { - // 16 bit - - while(*t) - { - *t = (*t >> 8) | (*t << 8); - ++t; - } - } - } - - //! returns if a format is little endian - inline bool isLittleEndian(ETEXT_FORMAT f) - { - return f == ETF_ASCII || - f == ETF_UTF8 || - f == ETF_UTF16_LE || - f == ETF_UTF32_LE; - } - - - //! returns true if a character is whitespace - inline bool isWhiteSpace(char_type c) - { - return (c==' ' || c=='\t' || c=='\n' || c=='\r'); - } - - - //! generates a list with xml special characters - void createSpecialCharacterList() - { - // list of strings containing special symbols, - // the first character is the special character, - // the following is the symbol string without trailing &. - - SpecialCharacters.push_back("&"); - SpecialCharacters.push_back("gt;"); - SpecialCharacters.push_back("\"quot;"); - SpecialCharacters.push_back("'apos;"); - - } - - - //! compares the first n characters of the strings - bool equalsn(const char_type* str1, const char_type* str2, int len) - { - int i; - for(i=0; str1[i] && str2[i] && i < len; ++i) - if (str1[i] != str2[i]) - return false; - - // if one (or both) of the strings was smaller then they - // are only equal if they have the same lenght - return (i == len) || (str1[i] == 0 && str2[i] == 0); - } - - - //! stores the target text format - void storeTargetFormat() - { - // get target format. We could have done this using template specialization, - // but VisualStudio 6 don't like it and we want to support it. - - switch(sizeof(char_type)) - { - case 1: - TargetFormat = ETF_UTF8; - break; - case 2: - TargetFormat = ETF_UTF16_LE; - break; - case 4: - TargetFormat = ETF_UTF32_LE; - break; - default: - TargetFormat = ETF_ASCII; // should never happen. - } - } - - - // instance variables: - - char_type* TextData; // data block of the text file - char_type* P; // current point in text to parse - char_type* TextBegin; // start of text to parse - unsigned int TextSize; // size of text to parse in characters, not bytes - - EXML_NODE CurrentNodeType; // type of the currently parsed node - ETEXT_FORMAT SourceFormat; // source format of the xml file - ETEXT_FORMAT TargetFormat; // output format of this parser - - core::string NodeName; // name of the node currently in - core::string EmptyString; // empty string to be returned by getSafe() methods - - bool IsEmptyElement; // is the currently parsed node empty? - - core::array< core::string > SpecialCharacters; // see createSpecialCharacterList() - - core::array Attributes; // attributes of current element - -}; // end CXMLReaderImpl - - -} // end namespace -} // end namespace - -#endif +// Copyright (C) 2002-2005 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine" and the "irrXML" project. +// For conditions of distribution and use, see copyright notice in irrlicht.h and/or irrXML.h + +#ifndef __ICXML_READER_IMPL_H_INCLUDED__ +#define __ICXML_READER_IMPL_H_INCLUDED__ + +#include "irrXML.h" +#include "irrString.h" +#include "irrArray.h" + +using namespace Assimp; + +#ifdef _DEBUG +#define IRR_DEBUGPRINT(x) printf((x)); +#else // _DEBUG +#define IRR_DEBUGPRINT(x) +#endif // _DEBUG + + +namespace irr +{ +namespace io +{ + + +//! implementation of the IrrXMLReader +template +class CXMLReaderImpl : public IIrrXMLReader +{ +public: + + //! Constructor + CXMLReaderImpl(IFileReadCallBack* callback, bool deleteCallBack = true) + : TextData(0), P(0), TextBegin(0), TextSize(0), CurrentNodeType(EXN_NONE), + SourceFormat(ETF_ASCII), TargetFormat(ETF_ASCII) + { + if (!callback) + return; + + storeTargetFormat(); + + // read whole xml file + + readFile(callback); + + // clean up + + if (deleteCallBack) + delete callback; + + // create list with special characters + + createSpecialCharacterList(); + + // set pointer to text begin + P = TextBegin; + } + + + //! Destructor + virtual ~CXMLReaderImpl() + { + delete [] TextData; + } + + + //! Reads forward to the next xml node. + //! \return Returns false, if there was no further node. + virtual bool read() + { + // if not end reached, parse the node + if (P && (unsigned int)(P - TextBegin) < TextSize - 1 && *P != 0) + { + parseCurrentNode(); + return true; + } + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; + } + + + //! Returns the type of the current XML node. + virtual EXML_NODE getNodeType() const + { + return CurrentNodeType; + } + + + //! Returns attribute count of the current XML node. + virtual int getAttributeCount() const + { + return Attributes.size(); + } + + + //! Returns name of an attribute. + virtual const char_type* getAttributeName(int idx) const + { + if (idx < 0 || idx >= (int)Attributes.size()) + return 0; + + return Attributes[idx].Name.c_str(); + } + + + //! Returns the value of an attribute. + virtual const char_type* getAttributeValue(int idx) const + { + if (idx < 0 || idx >= (int)Attributes.size()) + return 0; + + return Attributes[idx].Value.c_str(); + } + + + //! Returns the value of an attribute. + virtual const char_type* getAttributeValue(const char_type* name) const + { + const SAttribute* attr = getAttributeByName(name); + if (!attr) + return 0; + + return attr->Value.c_str(); + } + + + //! Returns the value of an attribute + virtual const char_type* getAttributeValueSafe(const char_type* name) const + { + const SAttribute* attr = getAttributeByName(name); + if (!attr) + return EmptyString.c_str(); + + return attr->Value.c_str(); + } + + + + //! Returns the value of an attribute as integer. + int getAttributeValueAsInt(const char_type* name) const + { + return (int)getAttributeValueAsFloat(name); + } + + + //! Returns the value of an attribute as integer. + int getAttributeValueAsInt(int idx) const + { + return (int)getAttributeValueAsFloat(idx); + } + + + //! Returns the value of an attribute as float. + float getAttributeValueAsFloat(const char_type* name) const + { + const SAttribute* attr = getAttributeByName(name); + if (!attr) + return 0; + + core::stringc c = attr->Value.c_str(); + return fast_atof(c.c_str()); + } + + + //! Returns the value of an attribute as float. + float getAttributeValueAsFloat(int idx) const + { + const char_type* attrvalue = getAttributeValue(idx); + if (!attrvalue) + return 0; + + core::stringc c = attrvalue; + return fast_atof(c.c_str()); + } + + + //! Returns the name of the current node. + virtual const char_type* getNodeName() const + { + return NodeName.c_str(); + } + + + //! Returns data of the current node. + virtual const char_type* getNodeData() const + { + return NodeName.c_str(); + } + + + //! Returns if an element is an empty element, like + virtual bool isEmptyElement() const + { + return IsEmptyElement; + } + + //! Returns format of the source xml file. + virtual ETEXT_FORMAT getSourceFormat() const + { + return SourceFormat; + } + + //! Returns format of the strings returned by the parser. + virtual ETEXT_FORMAT getParserFormat() const + { + return TargetFormat; + } + +private: + + // Reads the current xml node + void parseCurrentNode() + { + char_type* start = P; + + // move forward until '<' found + while(*P != L'<' && *P) + ++P; + + if (!*P) + return; + + if (P - start > 0) + { + // we found some text, store it + if (setText(start, P)) + return; + } + + ++P; + + // based on current token, parse and report next element + switch(*P) + { + case L'/': + parseClosingXMLElement(); + break; + case L'?': + ignoreDefinition(); + break; + case L'!': + if (!parseCDATA()) + parseComment(); + break; + default: + parseOpeningXMLElement(); + break; + } + } + + + //! sets the state that text was found. Returns true if set should be set + bool setText(char_type* start, char_type* end) + { + // check if text is more than 2 characters, and if not, check if there is + // only white space, so that this text won't be reported + if (end - start < 3) + { + char_type* p = start; + for(; p != end; ++p) + if (!isWhiteSpace(*p)) + break; + + if (p == end) + return false; + } + + // set current text to the parsed text, and replace xml special characters + core::string s(start, (int)(end - start)); + NodeName = replaceSpecialCharacters(s); + + // current XML node type is text + CurrentNodeType = EXN_TEXT; + + return true; + } + + + + //! ignores an xml definition like + void ignoreDefinition() + { + CurrentNodeType = EXN_UNKNOWN; + + // move until end marked with '>' reached + while(*P != L'>') + ++P; + + ++P; + } + + + //! parses a comment + void parseComment() + { + CurrentNodeType = EXN_COMMENT; + P += 1; + + char_type *pCommentBegin = P; + + int count = 1; + + // move until end of comment reached + while(count) + { + if (*P == L'>') + --count; + else + if (*P == L'<') + ++count; + + ++P; + } + + P -= 3; + NodeName = core::string(pCommentBegin+2, (int)(P - pCommentBegin-2)); + P += 3; + } + + + //! parses an opening xml element and reads attributes + void parseOpeningXMLElement() + { + CurrentNodeType = EXN_ELEMENT; + IsEmptyElement = false; + Attributes.clear(); + + // find name + const char_type* startName = P; + + // find end of element + while(*P != L'>' && !isWhiteSpace(*P)) + ++P; + + const char_type* endName = P; + + // find Attributes + while(*P != L'>') + { + if (isWhiteSpace(*P)) + ++P; + else + { + if (*P != L'/') + { + // we've got an attribute + + // read the attribute names + const char_type* attributeNameBegin = P; + + while(!isWhiteSpace(*P) && *P != L'=') + ++P; + + const char_type* attributeNameEnd = P; + ++P; + + // read the attribute value + // check for quotes and single quotes, thx to murphy + while( (*P != L'\"') && (*P != L'\'') && *P) + ++P; + + if (!*P) // malformatted xml file + return; + + const char_type attributeQuoteChar = *P; + + ++P; + const char_type* attributeValueBegin = P; + + while(*P != attributeQuoteChar && *P) + ++P; + + if (!*P) // malformatted xml file + return; + + const char_type* attributeValueEnd = P; + ++P; + + SAttribute attr; + attr.Name = core::string(attributeNameBegin, + (int)(attributeNameEnd - attributeNameBegin)); + + core::string s(attributeValueBegin, + (int)(attributeValueEnd - attributeValueBegin)); + + attr.Value = replaceSpecialCharacters(s); + Attributes.push_back(attr); + } + else + { + // tag is closed directly + ++P; + IsEmptyElement = true; + break; + } + } + } + + // check if this tag is closing directly + if (endName > startName && *(endName-1) == L'/') + { + // directly closing tag + IsEmptyElement = true; + endName--; + } + + NodeName = core::string(startName, (int)(endName - startName)); + + ++P; + } + + + //! parses an closing xml tag + void parseClosingXMLElement() + { + CurrentNodeType = EXN_ELEMENT_END; + IsEmptyElement = false; + Attributes.clear(); + + ++P; + const char_type* pBeginClose = P; + + while(*P != L'>') + ++P; + + // remove trailing whitespace, if any + while( isspace( P[-1])) + --P; + + NodeName = core::string(pBeginClose, (int)(P - pBeginClose)); + ++P; + } + + //! parses a possible CDATA section, returns false if begin was not a CDATA section + bool parseCDATA() + { + if (*(P+1) != L'[') + return false; + + CurrentNodeType = EXN_CDATA; + + // skip '' && + (*(P-1) == L']') && + (*(P-2) == L']')) + { + cDataEnd = P - 2; + } + + ++P; + } + + if ( cDataEnd ) + NodeName = core::string(cDataBegin, (int)(cDataEnd - cDataBegin)); + else + NodeName = ""; + + return true; + } + + + // structure for storing attribute-name pairs + struct SAttribute + { + core::string Name; + core::string Value; + }; + + // finds a current attribute by name, returns 0 if not found + const SAttribute* getAttributeByName(const char_type* name) const + { + if (!name) + return 0; + + core::string n = name; + + for (int i=0; i<(int)Attributes.size(); ++i) + if (Attributes[i].Name == n) + return &Attributes[i]; + + return 0; + } + + // replaces xml special characters in a string and creates a new one + core::string replaceSpecialCharacters( + core::string& origstr) + { + int pos = origstr.findFirst(L'&'); + int oldPos = 0; + + if (pos == -1) + return origstr; + + core::string newstr; + + while(pos != -1 && pos < origstr.size()-2) + { + // check if it is one of the special characters + + int specialChar = -1; + for (int i=0; i<(int)SpecialCharacters.size(); ++i) + { + const char_type* p = &origstr.c_str()[pos]+1; + + if (equalsn(&SpecialCharacters[i][1], p, SpecialCharacters[i].size()-1)) + { + specialChar = i; + break; + } + } + + if (specialChar != -1) + { + newstr.append(origstr.subString(oldPos, pos - oldPos)); + newstr.append(SpecialCharacters[specialChar][0]); + pos += SpecialCharacters[specialChar].size(); + } + else + { + newstr.append(origstr.subString(oldPos, pos - oldPos + 1)); + pos += 1; + } + + // find next & + oldPos = pos; + pos = origstr.findNext(L'&', pos); + } + + if (oldPos < origstr.size()-1) + newstr.append(origstr.subString(oldPos, origstr.size()-oldPos)); + + return newstr; + } + + + + //! reads the xml file and converts it into the wanted character format. + bool readFile(IFileReadCallBack* callback) + { + int size = callback->getSize(); + size += 4; // We need two terminating 0's at the end. + // For ASCII we need 1 0's, for UTF-16 2, for UTF-32 4. + + char* data8 = new char[size]; + + if (!callback->read(data8, size-4)) + { + delete [] data8; + return false; + } + + // add zeros at end + + data8[size-1] = 0; + data8[size-2] = 0; + data8[size-3] = 0; + data8[size-4] = 0; + + char16* data16 = reinterpret_cast(data8); + char32* data32 = reinterpret_cast(data8); + + // now we need to convert the data to the desired target format + // based on the byte order mark. + + const unsigned char UTF8[] = {0xEF, 0xBB, 0xBF}; // 0xEFBBBF; + const int UTF16_BE = 0xFFFE; + const int UTF16_LE = 0xFEFF; + const int UTF32_BE = 0xFFFE0000; + const int UTF32_LE = 0x0000FEFF; + + // check source for all utf versions and convert to target data format + + if (size >= 4 && data32[0] == (char32)UTF32_BE) + { + // UTF-32, big endian + SourceFormat = ETF_UTF32_BE; + convertTextData(data32+1, data8, (size/4)); // data32+1 because we need to skip the header + } + else + if (size >= 4 && data32[0] == (char32)UTF32_LE) + { + // UTF-32, little endian + SourceFormat = ETF_UTF32_LE; + convertTextData(data32+1, data8, (size/4)); // data32+1 because we need to skip the header + } + else + if (size >= 2 && data16[0] == UTF16_BE) + { + // UTF-16, big endian + SourceFormat = ETF_UTF16_BE; + convertTextData(data16+1, data8, (size/2)); // data16+1 because we need to skip the header + } + else + if (size >= 2 && data16[0] == UTF16_LE) + { + // UTF-16, little endian + SourceFormat = ETF_UTF16_LE; + convertTextData(data16+1, data8, (size/2)); // data16+1 because we need to skip the header + } + else + if (size >= 3 && data8[0] == UTF8[0] && data8[1] == UTF8[1] && data8[2] == UTF8[2]) + { + // UTF-8 + SourceFormat = ETF_UTF8; + convertTextData(data8+3, data8, size); // data8+3 because we need to skip the header + } + else + { + // ASCII + SourceFormat = ETF_ASCII; + convertTextData(data8, data8, size); + } + + return true; + } + + + //! converts the text file into the desired format. + //! \param source: begin of the text (without byte order mark) + //! \param pointerToStore: pointer to text data block which can be + //! stored or deleted based on the nesessary conversion. + //! \param sizeWithoutHeader: Text size in characters without header + template + void convertTextData(src_char_type* source, char* pointerToStore, int sizeWithoutHeader) + { + // convert little to big endian if necessary + if (sizeof(src_char_type) > 1 && + isLittleEndian(TargetFormat) != isLittleEndian(SourceFormat)) + convertToLittleEndian(source); + + // check if conversion is necessary: + if (sizeof(src_char_type) == sizeof(char_type)) + { + // no need to convert + TextBegin = (char_type*)source; + TextData = (char_type*)pointerToStore; + TextSize = sizeWithoutHeader; + } + else + { + // convert source into target data format. + // TODO: implement a real conversion. This one just + // copies bytes. This is a problem when there are + // unicode symbols using more than one character. + + TextData = new char_type[sizeWithoutHeader]; + + // MSVC debugger complains here about loss of data ... + + + // FIXME - gcc complains about 'shift width larger than width of type' + // for T == unsigned long. Avoid it by messing around volatile .. + volatile unsigned int c = 3; + const src_char_type cc = (src_char_type)((((uint64_t)1u << (sizeof( char_type)< + void convertToLittleEndian(src_char_type* t) + { + if (sizeof(src_char_type) == 4) + { + // 32 bit + + while(*t) + { + *t = ((*t & 0xff000000) >> 24) | + ((*t & 0x00ff0000) >> 8) | + ((*t & 0x0000ff00) << 8) | + ((*t & 0x000000ff) << 24); + ++t; + } + } + else + { + // 16 bit + + while(*t) + { + *t = (*t >> 8) | (*t << 8); + ++t; + } + } + } + + //! returns if a format is little endian + inline bool isLittleEndian(ETEXT_FORMAT f) + { + return f == ETF_ASCII || + f == ETF_UTF8 || + f == ETF_UTF16_LE || + f == ETF_UTF32_LE; + } + + + //! returns true if a character is whitespace + inline bool isWhiteSpace(char_type c) + { + return (c==' ' || c=='\t' || c=='\n' || c=='\r'); + } + + + //! generates a list with xml special characters + void createSpecialCharacterList() + { + // list of strings containing special symbols, + // the first character is the special character, + // the following is the symbol string without trailing &. + + SpecialCharacters.push_back("&"); + SpecialCharacters.push_back("gt;"); + SpecialCharacters.push_back("\"quot;"); + SpecialCharacters.push_back("'apos;"); + + } + + + //! compares the first n characters of the strings + bool equalsn(const char_type* str1, const char_type* str2, int len) + { + int i; + for(i=0; str1[i] && str2[i] && i < len; ++i) + if (str1[i] != str2[i]) + return false; + + // if one (or both) of the strings was smaller then they + // are only equal if they have the same lenght + return (i == len) || (str1[i] == 0 && str2[i] == 0); + } + + + //! stores the target text format + void storeTargetFormat() + { + // get target format. We could have done this using template specialization, + // but VisualStudio 6 don't like it and we want to support it. + + switch(sizeof(char_type)) + { + case 1: + TargetFormat = ETF_UTF8; + break; + case 2: + TargetFormat = ETF_UTF16_LE; + break; + case 4: + TargetFormat = ETF_UTF32_LE; + break; + default: + TargetFormat = ETF_ASCII; // should never happen. + } + } + + + // instance variables: + + char_type* TextData; // data block of the text file + char_type* P; // current point in text to parse + char_type* TextBegin; // start of text to parse + unsigned int TextSize; // size of text to parse in characters, not bytes + + EXML_NODE CurrentNodeType; // type of the currently parsed node + ETEXT_FORMAT SourceFormat; // source format of the xml file + ETEXT_FORMAT TargetFormat; // output format of this parser + + core::string NodeName; // name of the node currently in + core::string EmptyString; // empty string to be returned by getSafe() methods + + bool IsEmptyElement; // is the currently parsed node empty? + + core::array< core::string > SpecialCharacters; // see createSpecialCharacterList() + + core::array Attributes; // attributes of current element + +}; // end CXMLReaderImpl + + +} // end namespace +} // end namespace + +#endif diff --git a/contrib/irrXML/heapsort.h b/contrib/irrXML/heapsort.h index 4395119df..d0db319d0 100644 --- a/contrib/irrXML/heapsort.h +++ b/contrib/irrXML/heapsort.h @@ -1,73 +1,73 @@ -// Copyright (C) 2002-2005 Nikolaus Gebhardt -// This file is part of the "Irrlicht Engine". -// For conditions of distribution and use, see copyright notice in irrlicht.h - -#ifndef __IRR_HEAPSORT_H_INCLUDED__ -#define __IRR_HEAPSORT_H_INCLUDED__ - -#include "irrTypes.h" - -namespace irr -{ -namespace core -{ - -//! Sinks an element into the heap. -template -inline void heapsink(T*array, s32 element, s32 max) -{ - while ((element<<1) < max) // there is a left child - { - s32 j = (element<<1); - - if (j+1 < max && array[j] < array[j+1]) - j = j+1; // take right child - - if (array[element] < array[j]) - { - T t = array[j]; // swap elements - array[j] = array[element]; - array[element] = t; - element = j; - } - else - return; - } -} - - -//! Sorts an array with size 'size' using heapsort. -template -inline void heapsort(T* array_, s32 size) -{ - // for heapsink we pretent this is not c++, where - // arrays start with index 0. So we decrease the array pointer, - // the maximum always +2 and the element always +1 - - T* virtualArray = array_ - 1; - s32 virtualSize = size + 2; - s32 i; - - // build heap - - for (i=((size-1)/2); i>=0; --i) - heapsink(virtualArray, i+1, virtualSize-1); - - // sort array - - for (i=size-1; i>=0; --i) - { - T t = array_[0]; - array_[0] = array_[i]; - array_[i] = t; - heapsink(virtualArray, 1, i + 1); - } -} - -} // end namespace core -} // end namespace irr - - - -#endif - +// Copyright (C) 2002-2005 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_HEAPSORT_H_INCLUDED__ +#define __IRR_HEAPSORT_H_INCLUDED__ + +#include "irrTypes.h" + +namespace irr +{ +namespace core +{ + +//! Sinks an element into the heap. +template +inline void heapsink(T*array, s32 element, s32 max) +{ + while ((element<<1) < max) // there is a left child + { + s32 j = (element<<1); + + if (j+1 < max && array[j] < array[j+1]) + j = j+1; // take right child + + if (array[element] < array[j]) + { + T t = array[j]; // swap elements + array[j] = array[element]; + array[element] = t; + element = j; + } + else + return; + } +} + + +//! Sorts an array with size 'size' using heapsort. +template +inline void heapsort(T* array_, s32 size) +{ + // for heapsink we pretent this is not c++, where + // arrays start with index 0. So we decrease the array pointer, + // the maximum always +2 and the element always +1 + + T* virtualArray = array_ - 1; + s32 virtualSize = size + 2; + s32 i; + + // build heap + + for (i=((size-1)/2); i>=0; --i) + heapsink(virtualArray, i+1, virtualSize-1); + + // sort array + + for (i=size-1; i>=0; --i) + { + T t = array_[0]; + array_[0] = array_[i]; + array_[i] = t; + heapsink(virtualArray, 1, i + 1); + } +} + +} // end namespace core +} // end namespace irr + + + +#endif + diff --git a/contrib/irrXML/irrArray.h b/contrib/irrXML/irrArray.h index 4bcf1fc11..40c822590 100644 --- a/contrib/irrXML/irrArray.h +++ b/contrib/irrXML/irrArray.h @@ -1,444 +1,444 @@ -// Copyright (C) 2002-2005 Nikolaus Gebhardt -// This file is part of the "Irrlicht Engine" and the "irrXML" project. -// For conditions of distribution and use, see copyright notice in irrlicht.h and irrXML.h - -#ifndef __IRR_ARRAY_H_INCLUDED__ -#define __IRR_ARRAY_H_INCLUDED__ - -#include "irrTypes.h" -#include "heapsort.h" - -namespace irr -{ -namespace core -{ - -//! Self reallocating template array (like stl vector) with additional features. -/** Some features are: Heap sorting, binary search methods, easier debugging. -*/ -template -class array -{ - -public: - - array() - : data(0), allocated(0), used(0), - free_when_destroyed(true), is_sorted(true) - { - } - - //! Constructs a array and allocates an initial chunk of memory. - //! \param start_count: Amount of elements to allocate. - array(u32 start_count) - : data(0), allocated(0), used(0), - free_when_destroyed(true), is_sorted(true) - { - reallocate(start_count); - } - - - //! Copy constructor - array(const array& other) - : data(0) - { - *this = other; - } - - - - //! Destructor. Frees allocated memory, if set_free_when_destroyed - //! was not set to false by the user before. - ~array() - { - if (free_when_destroyed) - delete [] data; - } - - - - //! Reallocates the array, make it bigger or smaller. - //! \param new_size: New size of array. - void reallocate(u32 new_size) - { - T* old_data = data; - - data = new T[new_size]; - allocated = new_size; - - s32 end = used < new_size ? used : new_size; - for (s32 i=0; i allocated) - { - // reallocate(used * 2 +1); - // this doesn't work if the element is in the same array. So - // we'll copy the element first to be sure we'll get no data - // corruption - - T e; - e = element; // copy element - reallocate(used * 2 +1); // increase data block - data[used++] = e; // push_back - is_sorted = false; - return; - } - - data[used++] = element; - is_sorted = false; - } - - - //! Adds an element at the front of the array. If the array is to small to - //! add this new element, the array is made bigger. Please note that this - //! is slow, because the whole array needs to be copied for this. - //! \param element: Element to add at the back of the array. - void push_front(const T& element) - { - if (used + 1 > allocated) - reallocate(used * 2 +1); - - for (int i=(int)used; i>0; --i) - data[i] = data[i-1]; - - data[0] = element; - is_sorted = false; - ++used; - } - - - //! Insert item into array at specified position. Please use this - //! only if you know what you are doing (possible performance loss). - //! The preferred method of adding elements should be push_back(). - //! \param element: Element to be inserted - //! \param index: Where position to insert the new element. - void insert(const T& element, u32 index=0) - { - _IRR_DEBUG_BREAK_IF(index>used) // access violation - - if (used + 1 > allocated) - reallocate(used * 2 +1); - - for (u32 i=used++; i>index; i--) - data[i] = data[i-1]; - - data[index] = element; - is_sorted = false; - } - - - - - //! Clears the array and deletes all allocated memory. - void clear() - { - delete [] data; - data = 0; - used = 0; - allocated = 0; - is_sorted = true; - } - - - - //! Sets pointer to new array, using this as new workspace. - //! \param newPointer: Pointer to new array of elements. - //! \param size: Size of the new array. - void set_pointer(T* newPointer, u32 size) - { - delete [] data; - data = newPointer; - allocated = size; - used = size; - is_sorted = false; - } - - - - //! Sets if the array should delete the memory it used. - //! \param f: If true, the array frees the allocated memory in its - //! destructor, otherwise not. The default is true. - void set_free_when_destroyed(bool f) - { - free_when_destroyed = f; - } - - - - //! Sets the size of the array. - //! \param usedNow: Amount of elements now used. - void set_used(u32 usedNow) - { - if (allocated < usedNow) - reallocate(usedNow); - - used = usedNow; - } - - - - //! Assignement operator - void operator=(const array& other) - { - if (data) - delete [] data; - - //if (allocated < other.allocated) - if (other.allocated == 0) - data = 0; - else - data = new T[other.allocated]; - - used = other.used; - free_when_destroyed = other.free_when_destroyed; - is_sorted = other.is_sorted; - allocated = other.allocated; - - for (u32 i=0; i=used) // access violation - - return data[index]; - } - - - - //! Direct access operator - const T& operator [](u32 index) const - { - _IRR_DEBUG_BREAK_IF(index>=used) // access violation - - return data[index]; - } - - //! Gets last frame - const T& getLast() const - { - _IRR_DEBUG_BREAK_IF(!used) // access violation - - return data[used-1]; - } - - //! Gets last frame - T& getLast() - { - _IRR_DEBUG_BREAK_IF(!used) // access violation - - return data[used-1]; - } - - - //! Returns a pointer to the array. - //! \return Pointer to the array. - T* pointer() - { - return data; - } - - - - //! Returns a const pointer to the array. - //! \return Pointer to the array. - const T* const_pointer() const - { - return data; - } - - - - //! Returns size of used array. - //! \return Size of elements in the array. - u32 size() const - { - return used; - } - - - - //! Returns amount memory allocated. - //! \return Returns amount of memory allocated. The amount of bytes - //! allocated would be allocated_size() * sizeof(ElementsUsed); - u32 allocated_size() const - { - return allocated; - } - - - - //! Returns true if array is empty - //! \return True if the array is empty, false if not. - bool empty() const - { - return used == 0; - } - - - - //! Sorts the array using heapsort. There is no additional memory waste and - //! the algorithm performs (O) n log n in worst case. - void sort() - { - if (is_sorted || used<2) - return; - - heapsort(data, used); - is_sorted = true; - } - - - - //! Performs a binary search for an element, returns -1 if not found. - //! The array will be sorted before the binary search if it is not - //! already sorted. - //! \param element: Element to search for. - //! \return Returns position of the searched element if it was found, - //! otherwise -1 is returned. - s32 binary_search(const T& element) - { - return binary_search(element, 0, used-1); - } - - - - //! Performs a binary search for an element, returns -1 if not found. - //! The array will be sorted before the binary search if it is not - //! already sorted. - //! \param element: Element to search for. - //! \param left: First left index - //! \param right: Last right index. - //! \return Returns position of the searched element if it was found, - //! otherwise -1 is returned. - s32 binary_search(const T& element, s32 left, s32 right) - { - if (!used) - return -1; - - sort(); - - s32 m; - - do - { - m = (left+right)>>1; - - if (element < data[m]) - right = m - 1; - else - left = m + 1; - - } while((element < data[m] || data[m] < element) && left<=right); - - // this last line equals to: - // " while((element != array[m]) && left<=right);" - // but we only want to use the '<' operator. - // the same in next line, it is "(element == array[m])" - - if (!(element < data[m]) && !(data[m] < element)) - return m; - - return -1; - } - - - //! Finds an element in linear time, which is very slow. Use - //! binary_search for faster finding. Only works if =operator is implemented. - //! \param element: Element to search for. - //! \return Returns position of the searched element if it was found, - //! otherwise -1 is returned. - s32 linear_search(T& element) - { - for (u32 i=0; i=0; --i) - if (data[i] == element) - return (s32)i; - - return -1; - } - - - - //! Erases an element from the array. May be slow, because all elements - //! following after the erased element have to be copied. - //! \param index: Index of element to be erased. - void erase(u32 index) - { - _IRR_DEBUG_BREAK_IF(index>=used || index<0) // access violation - - for (u32 i=index+1; i=used || index<0 || count<1 || index+count>used) // access violation - - for (u32 i=index+count; i +class array +{ + +public: + + array() + : data(0), allocated(0), used(0), + free_when_destroyed(true), is_sorted(true) + { + } + + //! Constructs a array and allocates an initial chunk of memory. + //! \param start_count: Amount of elements to allocate. + array(u32 start_count) + : data(0), allocated(0), used(0), + free_when_destroyed(true), is_sorted(true) + { + reallocate(start_count); + } + + + //! Copy constructor + array(const array& other) + : data(0) + { + *this = other; + } + + + + //! Destructor. Frees allocated memory, if set_free_when_destroyed + //! was not set to false by the user before. + ~array() + { + if (free_when_destroyed) + delete [] data; + } + + + + //! Reallocates the array, make it bigger or smaller. + //! \param new_size: New size of array. + void reallocate(u32 new_size) + { + T* old_data = data; + + data = new T[new_size]; + allocated = new_size; + + s32 end = used < new_size ? used : new_size; + for (s32 i=0; i allocated) + { + // reallocate(used * 2 +1); + // this doesn't work if the element is in the same array. So + // we'll copy the element first to be sure we'll get no data + // corruption + + T e; + e = element; // copy element + reallocate(used * 2 +1); // increase data block + data[used++] = e; // push_back + is_sorted = false; + return; + } + + data[used++] = element; + is_sorted = false; + } + + + //! Adds an element at the front of the array. If the array is to small to + //! add this new element, the array is made bigger. Please note that this + //! is slow, because the whole array needs to be copied for this. + //! \param element: Element to add at the back of the array. + void push_front(const T& element) + { + if (used + 1 > allocated) + reallocate(used * 2 +1); + + for (int i=(int)used; i>0; --i) + data[i] = data[i-1]; + + data[0] = element; + is_sorted = false; + ++used; + } + + + //! Insert item into array at specified position. Please use this + //! only if you know what you are doing (possible performance loss). + //! The preferred method of adding elements should be push_back(). + //! \param element: Element to be inserted + //! \param index: Where position to insert the new element. + void insert(const T& element, u32 index=0) + { + _IRR_DEBUG_BREAK_IF(index>used) // access violation + + if (used + 1 > allocated) + reallocate(used * 2 +1); + + for (u32 i=used++; i>index; i--) + data[i] = data[i-1]; + + data[index] = element; + is_sorted = false; + } + + + + + //! Clears the array and deletes all allocated memory. + void clear() + { + delete [] data; + data = 0; + used = 0; + allocated = 0; + is_sorted = true; + } + + + + //! Sets pointer to new array, using this as new workspace. + //! \param newPointer: Pointer to new array of elements. + //! \param size: Size of the new array. + void set_pointer(T* newPointer, u32 size) + { + delete [] data; + data = newPointer; + allocated = size; + used = size; + is_sorted = false; + } + + + + //! Sets if the array should delete the memory it used. + //! \param f: If true, the array frees the allocated memory in its + //! destructor, otherwise not. The default is true. + void set_free_when_destroyed(bool f) + { + free_when_destroyed = f; + } + + + + //! Sets the size of the array. + //! \param usedNow: Amount of elements now used. + void set_used(u32 usedNow) + { + if (allocated < usedNow) + reallocate(usedNow); + + used = usedNow; + } + + + + //! Assignement operator + void operator=(const array& other) + { + if (data) + delete [] data; + + //if (allocated < other.allocated) + if (other.allocated == 0) + data = 0; + else + data = new T[other.allocated]; + + used = other.used; + free_when_destroyed = other.free_when_destroyed; + is_sorted = other.is_sorted; + allocated = other.allocated; + + for (u32 i=0; i=used) // access violation + + return data[index]; + } + + + + //! Direct access operator + const T& operator [](u32 index) const + { + _IRR_DEBUG_BREAK_IF(index>=used) // access violation + + return data[index]; + } + + //! Gets last frame + const T& getLast() const + { + _IRR_DEBUG_BREAK_IF(!used) // access violation + + return data[used-1]; + } + + //! Gets last frame + T& getLast() + { + _IRR_DEBUG_BREAK_IF(!used) // access violation + + return data[used-1]; + } + + + //! Returns a pointer to the array. + //! \return Pointer to the array. + T* pointer() + { + return data; + } + + + + //! Returns a const pointer to the array. + //! \return Pointer to the array. + const T* const_pointer() const + { + return data; + } + + + + //! Returns size of used array. + //! \return Size of elements in the array. + u32 size() const + { + return used; + } + + + + //! Returns amount memory allocated. + //! \return Returns amount of memory allocated. The amount of bytes + //! allocated would be allocated_size() * sizeof(ElementsUsed); + u32 allocated_size() const + { + return allocated; + } + + + + //! Returns true if array is empty + //! \return True if the array is empty, false if not. + bool empty() const + { + return used == 0; + } + + + + //! Sorts the array using heapsort. There is no additional memory waste and + //! the algorithm performs (O) n log n in worst case. + void sort() + { + if (is_sorted || used<2) + return; + + heapsort(data, used); + is_sorted = true; + } + + + + //! Performs a binary search for an element, returns -1 if not found. + //! The array will be sorted before the binary search if it is not + //! already sorted. + //! \param element: Element to search for. + //! \return Returns position of the searched element if it was found, + //! otherwise -1 is returned. + s32 binary_search(const T& element) + { + return binary_search(element, 0, used-1); + } + + + + //! Performs a binary search for an element, returns -1 if not found. + //! The array will be sorted before the binary search if it is not + //! already sorted. + //! \param element: Element to search for. + //! \param left: First left index + //! \param right: Last right index. + //! \return Returns position of the searched element if it was found, + //! otherwise -1 is returned. + s32 binary_search(const T& element, s32 left, s32 right) + { + if (!used) + return -1; + + sort(); + + s32 m; + + do + { + m = (left+right)>>1; + + if (element < data[m]) + right = m - 1; + else + left = m + 1; + + } while((element < data[m] || data[m] < element) && left<=right); + + // this last line equals to: + // " while((element != array[m]) && left<=right);" + // but we only want to use the '<' operator. + // the same in next line, it is "(element == array[m])" + + if (!(element < data[m]) && !(data[m] < element)) + return m; + + return -1; + } + + + //! Finds an element in linear time, which is very slow. Use + //! binary_search for faster finding. Only works if =operator is implemented. + //! \param element: Element to search for. + //! \return Returns position of the searched element if it was found, + //! otherwise -1 is returned. + s32 linear_search(T& element) + { + for (u32 i=0; i=0; --i) + if (data[i] == element) + return (s32)i; + + return -1; + } + + + + //! Erases an element from the array. May be slow, because all elements + //! following after the erased element have to be copied. + //! \param index: Index of element to be erased. + void erase(u32 index) + { + _IRR_DEBUG_BREAK_IF(index>=used || index<0) // access violation + + for (u32 i=index+1; i=used || index<0 || count<1 || index+count>used) // access violation + + for (u32 i=index+count; i and string work both with unicode AND ascii, -so you can assign unicode to string and ascii to string -(and the other way round) if your ever would want to. -Note that the conversation between both is not done using an encoding. - -Known bugs: -Special characters like 'Ä', 'Ü' and 'Ö' are ignored in the -methods make_upper, make_lower and equals_ignore_case. -*/ -template -class string -{ -public: - - //! Default constructor - string() - : array(0), allocated(1), used(1) - { - array = new T[1]; - array[0] = 0x0; - } - - - - //! Constructor - string(const string& other) - : array(0), allocated(0), used(0) - { - *this = other; - } - - - //! Constructs a string from an int - string(int number) - : array(0), allocated(0), used(0) - { - // store if negative and make positive - - bool negative = false; - if (number < 0) - { - number *= -1; - negative = true; - } - - // temporary buffer for 16 numbers - - c8 tmpbuf[16]; - tmpbuf[15] = 0; - s32 idx = 15; - - // special case '0' - - if (!number) - { - tmpbuf[14] = '0'; - *this = &tmpbuf[14]; - return; - } - - // add numbers - - while(number && idx) - { - idx--; - tmpbuf[idx] = (c8)('0' + (number % 10)); - number = number / 10; - } - - // add sign - - if (negative) - { - idx--; - tmpbuf[idx] = '-'; - } - - *this = &tmpbuf[idx]; - } - - - - //! Constructor for copying a string from a pointer with a given lenght - template - string(const B* c, s32 lenght) - : array(0), allocated(0), used(0) - { - if (!c) - return; - - allocated = used = lenght+1; - array = new T[used]; - - for (s32 l = 0; l - string(const B* c) - : array(0),allocated(0), used(0) - { - *this = c; - } - - - - //! destructor - ~string() - { - delete [] array; - } - - - - //! Assignment operator - string& operator=(const string& other) - { - if (this == &other) - return *this; - - delete [] array; - allocated = used = other.size()+1; - array = new T[used]; - - const T* p = other.c_str(); - for (s32 i=0; i - string& operator=(const B* c) - { - if (!c) - { - if (!array) - { - array = new T[1]; - allocated = 1; - used = 1; - } - array[0] = 0x0; - return *this; - } - - if ((void*)c == (void*)array) - return *this; - - s32 len = 0; - const B* p = c; - while(*p) - { - ++len; - ++p; - } - - // we'll take the old string for a while, because the new string could be - // a part of the current string. - T* oldArray = array; - - allocated = used = len+1; - array = new T[used]; - - for (s32 l = 0; l operator+(const string& other) - { - string str(*this); - str.append(other); - - return str; - } - - //! Add operator for strings, ascii and unicode - template - string operator+(const B* c) - { - string str(*this); - str.append(c); - - return str; - } - - - - //! Direct access operator - T& operator [](const s32 index) const - { - _IRR_DEBUG_BREAK_IF(index>=used) // bad index - - return array[index]; - } - - - //! Comparison operator - bool operator ==(const T* str) const - { - int i; - for(i=0; array[i] && str[i]; ++i) - if (array[i] != str[i]) - return false; - - return !array[i] && !str[i]; - } - - - - //! Comparison operator - bool operator ==(const string& other) const - { - for(s32 i=0; array[i] && other.array[i]; ++i) - if (array[i] != other.array[i]) - return false; - - return used == other.used; - } - - - - //! Is smaller operator - bool operator <(const string& other) const - { - for(s32 i=0; array[i] && other.array[i]; ++i) - if (array[i] != other.array[i]) - return (array[i] < other.array[i]); - - return used < other.used; - } - - - - //! Equals not operator - bool operator !=(const string& other) const - { - return !(*this == other); - } - - - - //! Returns length of string - /** \return Returns length of the string in characters. */ - s32 size() const - { - return used-1; - } - - - - //! Returns character string - /** \return Returns pointer to C-style zero terminated string. */ - const T* c_str() const - { - return array; - } - - - - //! Makes the string lower case. - void make_lower() - { - const T A = (T)'A'; - const T Z = (T)'Z'; - const T diff = (T)'a' - A; - - for (s32 i=0; i=A && array[i]<=Z) - array[i] += diff; - } - } - - - - //! Makes the string upper case. - void make_upper() - { - const T a = (T)'a'; - const T z = (T)'z'; - const T diff = (T)'A' - a; - - for (s32 i=0; i=a && array[i]<=z) - array[i] += diff; - } - } - - - - //! Compares the string ignoring case. - /** \param other: Other string to compare. - \return Returns true if the string are equal ignoring case. */ - bool equals_ignore_case(const string& other) const - { - for(s32 i=0; array[i] && other[i]; ++i) - if (toLower(array[i]) != toLower(other[i])) - return false; - - return used == other.used; - } - - - //! compares the first n characters of the strings - bool equalsn(const string& other, int len) - { - int i; - for(i=0; array[i] && other[i] && i < len; ++i) - if (array[i] != other[i]) - return false; - - // if one (or both) of the strings was smaller then they - // are only equal if they have the same lenght - return (i == len) || (used == other.used); - } - - - //! compares the first n characters of the strings - bool equalsn(const T* str, int len) - { - int i; - for(i=0; array[i] && str[i] && i < len; ++i) - if (array[i] != str[i]) - return false; - - // if one (or both) of the strings was smaller then they - // are only equal if they have the same lenght - return (i == len) || (array[i] == 0 && str[i] == 0); - } - - - //! Appends a character to this string - /** \param character: Character to append. */ - void append(T character) - { - if (used + 1 > allocated) - reallocate((s32)used + 1); - - used += 1; - - array[used-2] = character; - array[used-1] = 0; - } - - //! Appends a string to this string - /** \param other: String to append. */ - void append(const string& other) - { - --used; - - s32 len = other.size(); - - if (used + len + 1 > allocated) - reallocate((s32)used + (s32)len + 1); - - for (s32 l=0; l& other, s32 length) - { - s32 len = other.size(); - - if (len < length) - { - append(other); - return; - } - - len = length; - --used; - - if (used + len > allocated) - reallocate((s32)used + (s32)len); - - for (s32 l=0; l - s32 findFirstCharNotInList(B* c, int count) const - { - for (int i=0; i - s32 findLastCharNotInList(B* c, int count) const - { - for (int i=used-2; i>=0; --i) - { - int j; - for (j=0; j=0; --i) - if (array[i] == c) - return i; - - return -1; - } - - - //! Returns a substring - //! \param begin: Start of substring. - //! \param length: Length of substring. - string subString(s32 begin, s32 length) - { - if (length <= 0) - return string(""); - - string o; - o.reserve(length+1); - - for (s32 i=0; i& other) - { - append(other); - } - - void operator += (int i) - { - append(string(i)); - } - - //! replaces all characters of a special type with another one - void replace(T toReplace, T replaceWith) - { - for (s32 i=0; i=used || index<0) // access violation - - for (int i=index+1; i=(T)'A' && t<=(T)'Z') - return t + ((T)'a' - (T)'A'); - else - return t; - } - - //! Reallocate the array, make it bigger or smaler - void reallocate(s32 new_size) - { - T* old_array = array; - - array = new T[new_size]; - allocated = new_size; - - s32 amount = used < new_size ? used : new_size; - for (s32 i=0; i stringc; - -//! Typedef for wide character strings -typedef string stringw; - -} // end namespace core -} // end namespace irr - -#endif - +// Copyright (C) 2002-2005 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine" and the "irrXML" project. +// For conditions of distribution and use, see copyright notice in irrlicht.h and irrXML.h + +#ifndef __IRR_STRING_H_INCLUDED__ +#define __IRR_STRING_H_INCLUDED__ + +#include "irrTypes.h" + +namespace irr +{ +namespace core +{ + +//! Very simple string class with some useful features. +/** string and string work both with unicode AND ascii, +so you can assign unicode to string and ascii to string +(and the other way round) if your ever would want to. +Note that the conversation between both is not done using an encoding. + +Known bugs: +Special characters like 'Ä', 'Ü' and 'Ö' are ignored in the +methods make_upper, make_lower and equals_ignore_case. +*/ +template +class string +{ +public: + + //! Default constructor + string() + : array(0), allocated(1), used(1) + { + array = new T[1]; + array[0] = 0x0; + } + + + + //! Constructor + string(const string& other) + : array(0), allocated(0), used(0) + { + *this = other; + } + + + //! Constructs a string from an int + string(int number) + : array(0), allocated(0), used(0) + { + // store if negative and make positive + + bool negative = false; + if (number < 0) + { + number *= -1; + negative = true; + } + + // temporary buffer for 16 numbers + + c8 tmpbuf[16]; + tmpbuf[15] = 0; + s32 idx = 15; + + // special case '0' + + if (!number) + { + tmpbuf[14] = '0'; + *this = &tmpbuf[14]; + return; + } + + // add numbers + + while(number && idx) + { + idx--; + tmpbuf[idx] = (c8)('0' + (number % 10)); + number = number / 10; + } + + // add sign + + if (negative) + { + idx--; + tmpbuf[idx] = '-'; + } + + *this = &tmpbuf[idx]; + } + + + + //! Constructor for copying a string from a pointer with a given lenght + template + string(const B* c, s32 lenght) + : array(0), allocated(0), used(0) + { + if (!c) + return; + + allocated = used = lenght+1; + array = new T[used]; + + for (s32 l = 0; l + string(const B* c) + : array(0),allocated(0), used(0) + { + *this = c; + } + + + + //! destructor + ~string() + { + delete [] array; + } + + + + //! Assignment operator + string& operator=(const string& other) + { + if (this == &other) + return *this; + + delete [] array; + allocated = used = other.size()+1; + array = new T[used]; + + const T* p = other.c_str(); + for (s32 i=0; i + string& operator=(const B* c) + { + if (!c) + { + if (!array) + { + array = new T[1]; + allocated = 1; + used = 1; + } + array[0] = 0x0; + return *this; + } + + if ((void*)c == (void*)array) + return *this; + + s32 len = 0; + const B* p = c; + while(*p) + { + ++len; + ++p; + } + + // we'll take the old string for a while, because the new string could be + // a part of the current string. + T* oldArray = array; + + allocated = used = len+1; + array = new T[used]; + + for (s32 l = 0; l operator+(const string& other) + { + string str(*this); + str.append(other); + + return str; + } + + //! Add operator for strings, ascii and unicode + template + string operator+(const B* c) + { + string str(*this); + str.append(c); + + return str; + } + + + + //! Direct access operator + T& operator [](const s32 index) const + { + _IRR_DEBUG_BREAK_IF(index>=used) // bad index + + return array[index]; + } + + + //! Comparison operator + bool operator ==(const T* str) const + { + int i; + for(i=0; array[i] && str[i]; ++i) + if (array[i] != str[i]) + return false; + + return !array[i] && !str[i]; + } + + + + //! Comparison operator + bool operator ==(const string& other) const + { + for(s32 i=0; array[i] && other.array[i]; ++i) + if (array[i] != other.array[i]) + return false; + + return used == other.used; + } + + + + //! Is smaller operator + bool operator <(const string& other) const + { + for(s32 i=0; array[i] && other.array[i]; ++i) + if (array[i] != other.array[i]) + return (array[i] < other.array[i]); + + return used < other.used; + } + + + + //! Equals not operator + bool operator !=(const string& other) const + { + return !(*this == other); + } + + + + //! Returns length of string + /** \return Returns length of the string in characters. */ + s32 size() const + { + return used-1; + } + + + + //! Returns character string + /** \return Returns pointer to C-style zero terminated string. */ + const T* c_str() const + { + return array; + } + + + + //! Makes the string lower case. + void make_lower() + { + const T A = (T)'A'; + const T Z = (T)'Z'; + const T diff = (T)'a' - A; + + for (s32 i=0; i=A && array[i]<=Z) + array[i] += diff; + } + } + + + + //! Makes the string upper case. + void make_upper() + { + const T a = (T)'a'; + const T z = (T)'z'; + const T diff = (T)'A' - a; + + for (s32 i=0; i=a && array[i]<=z) + array[i] += diff; + } + } + + + + //! Compares the string ignoring case. + /** \param other: Other string to compare. + \return Returns true if the string are equal ignoring case. */ + bool equals_ignore_case(const string& other) const + { + for(s32 i=0; array[i] && other[i]; ++i) + if (toLower(array[i]) != toLower(other[i])) + return false; + + return used == other.used; + } + + + //! compares the first n characters of the strings + bool equalsn(const string& other, int len) + { + int i; + for(i=0; array[i] && other[i] && i < len; ++i) + if (array[i] != other[i]) + return false; + + // if one (or both) of the strings was smaller then they + // are only equal if they have the same lenght + return (i == len) || (used == other.used); + } + + + //! compares the first n characters of the strings + bool equalsn(const T* str, int len) + { + int i; + for(i=0; array[i] && str[i] && i < len; ++i) + if (array[i] != str[i]) + return false; + + // if one (or both) of the strings was smaller then they + // are only equal if they have the same lenght + return (i == len) || (array[i] == 0 && str[i] == 0); + } + + + //! Appends a character to this string + /** \param character: Character to append. */ + void append(T character) + { + if (used + 1 > allocated) + reallocate((s32)used + 1); + + used += 1; + + array[used-2] = character; + array[used-1] = 0; + } + + //! Appends a string to this string + /** \param other: String to append. */ + void append(const string& other) + { + --used; + + s32 len = other.size(); + + if (used + len + 1 > allocated) + reallocate((s32)used + (s32)len + 1); + + for (s32 l=0; l& other, s32 length) + { + s32 len = other.size(); + + if (len < length) + { + append(other); + return; + } + + len = length; + --used; + + if (used + len > allocated) + reallocate((s32)used + (s32)len); + + for (s32 l=0; l + s32 findFirstCharNotInList(B* c, int count) const + { + for (int i=0; i + s32 findLastCharNotInList(B* c, int count) const + { + for (int i=used-2; i>=0; --i) + { + int j; + for (j=0; j=0; --i) + if (array[i] == c) + return i; + + return -1; + } + + + //! Returns a substring + //! \param begin: Start of substring. + //! \param length: Length of substring. + string subString(s32 begin, s32 length) + { + if (length <= 0) + return string(""); + + string o; + o.reserve(length+1); + + for (s32 i=0; i& other) + { + append(other); + } + + void operator += (int i) + { + append(string(i)); + } + + //! replaces all characters of a special type with another one + void replace(T toReplace, T replaceWith) + { + for (s32 i=0; i=used || index<0) // access violation + + for (int i=index+1; i=(T)'A' && t<=(T)'Z') + return t + ((T)'a' - (T)'A'); + else + return t; + } + + //! Reallocate the array, make it bigger or smaler + void reallocate(s32 new_size) + { + T* old_array = array; + + array = new T[new_size]; + allocated = new_size; + + s32 amount = used < new_size ? used : new_size; + for (s32 i=0; i stringc; + +//! Typedef for wide character strings +typedef string stringw; + +} // end namespace core +} // end namespace irr + +#endif + diff --git a/contrib/irrXML/irrTypes.h b/contrib/irrXML/irrTypes.h index f67be0657..a7f12ec75 100644 --- a/contrib/irrXML/irrTypes.h +++ b/contrib/irrXML/irrTypes.h @@ -1,108 +1,108 @@ -// Copyright (C) 2002-2005 Nikolaus Gebhardt -// This file is part of the "Irrlicht Engine". -// For conditions of distribution and use, see copyright notice in irrlicht.h - -#ifndef __IRR_TYPES_H_INCLUDED__ -#define __IRR_TYPES_H_INCLUDED__ - -namespace irr -{ - -//! 8 bit unsigned variable. -/** This is a typedef for unsigned char, it ensures portability of the engine. */ -typedef unsigned char u8; - -//! 8 bit signed variable. -/** This is a typedef for signed char, it ensures portability of the engine. */ -typedef signed char s8; - -//! 8 bit character variable. -/** This is a typedef for char, it ensures portability of the engine. */ -typedef char c8; - - - -//! 16 bit unsigned variable. -/** This is a typedef for unsigned short, it ensures portability of the engine. */ -typedef unsigned short u16; - -//! 16 bit signed variable. -/** This is a typedef for signed short, it ensures portability of the engine. */ -typedef signed short s16; - - - -//! 32 bit unsigned variable. -/** This is a typedef for unsigned int, it ensures portability of the engine. */ -typedef unsigned int u32; - -//! 32 bit signed variable. -/** This is a typedef for signed int, it ensures portability of the engine. */ -typedef signed int s32; - - - -// 64 bit signed variable. -// This is a typedef for __int64, it ensures portability of the engine. -// This type is currently not used by the engine and not supported by compilers -// other than Microsoft Compilers, so it is outcommented. -//typedef __int64 s64; - - - -//! 32 bit floating point variable. -/** This is a typedef for float, it ensures portability of the engine. */ -typedef float f32; - -//! 64 bit floating point variable. -/** This is a typedef for double, it ensures portability of the engine. */ -typedef double f64; - - -} // end namespace - - -// define the wchar_t type if not already built in. -#ifdef _MSC_VER -#ifndef _WCHAR_T_DEFINED -//! A 16 bit wide character type. -/** - Defines the wchar_t-type. - In VS6, its not possible to tell - the standard compiler to treat wchar_t as a built-in type, and - sometimes we just don't want to include the huge stdlib.h or wchar.h, - so we'll use this. -*/ -typedef unsigned short wchar_t; -#define _WCHAR_T_DEFINED -#endif // wchar is not defined -#endif // microsoft compiler - -//! define a break macro for debugging only in Win32 mode. -// WORKAROUND (assimp): remove __asm -#if defined(WIN32) && defined(_MSC_VER) && defined(_DEBUG) -#if defined(_M_IX86) -#define _IRR_DEBUG_BREAK_IF( _CONDITION_ ) /*if (_CONDITION_) {_asm int 3}*/ -#else -#define _IRR_DEBUG_BREAK_IF( _CONDITION_ ) -#endif -#else -#define _IRR_DEBUG_BREAK_IF( _CONDITION_ ) -#endif - -//! Defines a small statement to work around a microsoft compiler bug. -/** The microsft compiler 7.0 - 7.1 has a bug: -When you call unmanaged code that returns a bool type value of false from managed code, -the return value may appear as true. See -http://support.microsoft.com/default.aspx?kbid=823071 for details. -Compiler version defines: VC6.0 : 1200, VC7.0 : 1300, VC7.1 : 1310, VC8.0 : 1400*/ - -// WORKAROUND (assimp): remove __asm -#if defined(WIN32) && defined(_MSC_VER) && (_MSC_VER > 1299) && (_MSC_VER < 1400) -#define _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX /*__asm mov eax,100*/ -#else -#define _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX -#endif // _IRR_MANAGED_MARSHALLING_BUGFIX - -#endif // __IRR_TYPES_H_INCLUDED__ - +// Copyright (C) 2002-2005 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_TYPES_H_INCLUDED__ +#define __IRR_TYPES_H_INCLUDED__ + +namespace irr +{ + +//! 8 bit unsigned variable. +/** This is a typedef for unsigned char, it ensures portability of the engine. */ +typedef unsigned char u8; + +//! 8 bit signed variable. +/** This is a typedef for signed char, it ensures portability of the engine. */ +typedef signed char s8; + +//! 8 bit character variable. +/** This is a typedef for char, it ensures portability of the engine. */ +typedef char c8; + + + +//! 16 bit unsigned variable. +/** This is a typedef for unsigned short, it ensures portability of the engine. */ +typedef unsigned short u16; + +//! 16 bit signed variable. +/** This is a typedef for signed short, it ensures portability of the engine. */ +typedef signed short s16; + + + +//! 32 bit unsigned variable. +/** This is a typedef for unsigned int, it ensures portability of the engine. */ +typedef unsigned int u32; + +//! 32 bit signed variable. +/** This is a typedef for signed int, it ensures portability of the engine. */ +typedef signed int s32; + + + +// 64 bit signed variable. +// This is a typedef for __int64, it ensures portability of the engine. +// This type is currently not used by the engine and not supported by compilers +// other than Microsoft Compilers, so it is outcommented. +//typedef __int64 s64; + + + +//! 32 bit floating point variable. +/** This is a typedef for float, it ensures portability of the engine. */ +typedef float f32; + +//! 64 bit floating point variable. +/** This is a typedef for double, it ensures portability of the engine. */ +typedef double f64; + + +} // end namespace + + +// define the wchar_t type if not already built in. +#ifdef _MSC_VER +#ifndef _WCHAR_T_DEFINED +//! A 16 bit wide character type. +/** + Defines the wchar_t-type. + In VS6, its not possible to tell + the standard compiler to treat wchar_t as a built-in type, and + sometimes we just don't want to include the huge stdlib.h or wchar.h, + so we'll use this. +*/ +typedef unsigned short wchar_t; +#define _WCHAR_T_DEFINED +#endif // wchar is not defined +#endif // microsoft compiler + +//! define a break macro for debugging only in Win32 mode. +// WORKAROUND (assimp): remove __asm +#if defined(WIN32) && defined(_MSC_VER) && defined(_DEBUG) +#if defined(_M_IX86) +#define _IRR_DEBUG_BREAK_IF( _CONDITION_ ) /*if (_CONDITION_) {_asm int 3}*/ +#else +#define _IRR_DEBUG_BREAK_IF( _CONDITION_ ) +#endif +#else +#define _IRR_DEBUG_BREAK_IF( _CONDITION_ ) +#endif + +//! Defines a small statement to work around a microsoft compiler bug. +/** The microsft compiler 7.0 - 7.1 has a bug: +When you call unmanaged code that returns a bool type value of false from managed code, +the return value may appear as true. See +http://support.microsoft.com/default.aspx?kbid=823071 for details. +Compiler version defines: VC6.0 : 1200, VC7.0 : 1300, VC7.1 : 1310, VC8.0 : 1400*/ + +// WORKAROUND (assimp): remove __asm +#if defined(WIN32) && defined(_MSC_VER) && (_MSC_VER > 1299) && (_MSC_VER < 1400) +#define _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX /*__asm mov eax,100*/ +#else +#define _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX +#endif // _IRR_MANAGED_MARSHALLING_BUGFIX + +#endif // __IRR_TYPES_H_INCLUDED__ + diff --git a/contrib/irrXML/irrXML.h b/contrib/irrXML/irrXML.h index f9badbd83..b51ddeb54 100644 --- a/contrib/irrXML/irrXML.h +++ b/contrib/irrXML/irrXML.h @@ -1,540 +1,540 @@ -// Copyright (C) 2002-2005 Nikolaus Gebhardt -// This file is part of the "Irrlicht Engine" and the "irrXML" project. -// For conditions of distribution and use, see copyright notice in irrlicht.h and/or irrXML.h - -#ifndef __IRR_XML_H_INCLUDED__ -#define __IRR_XML_H_INCLUDED__ - -#include - -/** \mainpage irrXML 1.2 API documentation -
- - \section intro Introduction - - Welcome to the irrXML API documentation. - Here you'll find any information you'll need to develop applications with - irrXML. If you look for a tutorial on how to start, take a look at the \ref irrxmlexample, - at the homepage of irrXML at xml.irrlicht3d.org - or into the SDK in the directory \example. - - irrXML is intended to be a high speed and easy-to-use XML Parser for C++, and - this documentation is an important part of it. If you have any questions or - suggestions, just send a email to the author of the engine, Nikolaus Gebhardt - (niko (at) irrlicht3d.org). For more informations about this parser, see \ref history. - - \section features Features - - irrXML provides forward-only, read-only - access to a stream of non validated XML data. It was fully implemented by - Nikolaus Gebhardt. Its current features are: - - - It it fast as lighting and has very low memory usage. It was - developed with the intention of being used in 3D games, as it already has been. - - irrXML is very small: It only consists of 60 KB of code and can be added easily - to your existing project. - - Of course, it is platform independent and works with lots of compilers. - - It is able to parse ASCII, UTF-8, UTF-16 and UTF-32 text files, both in - little and big endian format. - - Independent of the input file format, the parser can return all strings in ASCII, UTF-8, - UTF-16 and UTF-32 format. - - With its optional file access abstraction it has the advantage that it can read not - only from files but from any type of data (memory, network, ...). For example when - used with the Irrlicht Engine, it directly reads from compressed .zip files. - - Just like the Irrlicht Engine for which it was originally created, it is extremely easy - to use. - - It has no external dependencies, it does not even need the STL. - - Although irrXML has some strenghts, it currently also has the following limitations: - - - The input xml file is not validated and assumed to be correct. - - \section irrxmlexample Example - - The following code demonstrates the basic usage of irrXML. A simple xml - file like this is parsed: - \code - - - - - - Welcome to the Mesh Viewer of the "Irrlicht Engine". - - - \endcode - - The code for parsing this file would look like this: - \code - #include - using namespace irr; // irrXML is located in the namespace irr::io - using namespace io; - - #include // we use STL strings to store data in this example - - void main() - { - // create the reader using one of the factory functions - - IrrXMLReader* xml = createIrrXMLReader("config.xml"); - - // strings for storing the data we want to get out of the file - std::string modelFile; - std::string messageText; - std::string caption; - - // parse the file until end reached - - while(xml && xml->read()) - { - switch(xml->getNodeType()) - { - case EXN_TEXT: - // in this xml file, the only text which occurs is the messageText - messageText = xml->getNodeData(); - break; - case EXN_ELEMENT: - { - if (!strcmp("model", xml->getNodeName())) - modelFile = xml->getAttributeValue("file"); - else - if (!strcmp("messageText", xml->getNodeName())) - caption = xml->getAttributeValue("caption"); - } - break; - } - } - - // delete the xml parser after usage - delete xml; - } - \endcode - - \section howto How to use - - Simply add the source files in the /src directory of irrXML to your project. Done. - - \section license License - - The irrXML license is based on the zlib license. Basicly, this means you can do with - irrXML whatever you want: - - Copyright (C) 2002-2005 Nikolaus Gebhardt - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source distribution. - - \section history History - - As lots of references in this documentation and the source show, this xml - parser has originally been a part of the - Irrlicht Engine. But because - the parser has become very useful with the latest release, people asked for a - separate version of it, to be able to use it in non Irrlicht projects. With - irrXML 1.0, this has now been done. -*/ - -namespace irr -{ -namespace io -{ - //! Enumeration of all supported source text file formats - enum ETEXT_FORMAT - { - //! ASCII, file without byte order mark, or not a text file - ETF_ASCII, - - //! UTF-8 format - ETF_UTF8, - - //! UTF-16 format, big endian - ETF_UTF16_BE, - - //! UTF-16 format, little endian - ETF_UTF16_LE, - - //! UTF-32 format, big endian - ETF_UTF32_BE, - - //! UTF-32 format, little endian - ETF_UTF32_LE - }; - - - //! Enumeration for all xml nodes which are parsed by IrrXMLReader - enum EXML_NODE - { - //! No xml node. This is usually the node if you did not read anything yet. - EXN_NONE, - - //! A xml element, like - EXN_ELEMENT, - - //! End of an xml element, like - EXN_ELEMENT_END, - - //! Text within a xml element: this is the text. - EXN_TEXT, - - //! An xml comment like <!-- I am a comment --> or a DTD definition. - EXN_COMMENT, - - //! An xml cdata section like <![CDATA[ this is some CDATA ]]> - EXN_CDATA, - - //! Unknown element. - EXN_UNKNOWN - }; - - //! Callback class for file read abstraction. - /** With this, it is possible to make the xml parser read in other things - than just files. The Irrlicht engine is using this for example to - read xml from compressed .zip files. To make the parser read in - any other data, derive a class from this interface, implement the - two methods to read your data and give a pointer to an instance of - your implementation when calling createIrrXMLReader(), - createIrrXMLReaderUTF16() or createIrrXMLReaderUTF32() */ - class IFileReadCallBack - { - public: - - //! virtual destructor - virtual ~IFileReadCallBack() {}; - - //! Reads an amount of bytes from the file. - /** \param buffer: Pointer to buffer where to read bytes will be written to. - \param sizeToRead: Amount of bytes to read from the file. - \return Returns how much bytes were read. */ - virtual int read(void* buffer, int sizeToRead) = 0; - - //! Returns size of file in bytes - virtual int getSize() = 0; - }; - - //! Empty class to be used as parent class for IrrXMLReader. - /** If you need another class as base class for the xml reader, you can do this by creating - the reader using for example new CXMLReaderImpl(yourcallback); - The Irrlicht Engine for example needs IUnknown as base class for every object to - let it automaticly reference countend, hence it replaces IXMLBase with IUnknown. - See irrXML.cpp on how this can be done in detail. */ - class IXMLBase - { - }; - - //! Interface providing easy read access to a XML file. - /** You can create an instance of this reader using one of the factory functions - createIrrXMLReader(), createIrrXMLReaderUTF16() and createIrrXMLReaderUTF32(). - If using the parser from the Irrlicht Engine, please use IFileSystem::createXMLReader() - instead. - For a detailed intro how to use the parser, see \ref irrxmlexample and \ref features. - - The typical usage of this parser looks like this: - \code - #include - using namespace irr; // irrXML is located in the namespace irr::io - using namespace io; - - void main() - { - // create the reader using one of the factory functions - IrrXMLReader* xml = createIrrXMLReader("config.xml"); - - if (xml == 0) - return; // file could not be opened - - // parse the file until end reached - while(xml->read()) - { - // based on xml->getNodeType(), do something. - } - - // delete the xml parser after usage - delete xml; - } - \endcode - See \ref irrxmlexample for a more detailed example. - */ - template - class IIrrXMLReader : public super_class - { - public: - - //! Destructor - virtual ~IIrrXMLReader() {}; - - //! Reads forward to the next xml node. - /** \return Returns false, if there was no further node. */ - virtual bool read() = 0; - - //! Returns the type of the current XML node. - virtual EXML_NODE getNodeType() const = 0; - - //! Returns attribute count of the current XML node. - /** This is usually - non null if the current node is EXN_ELEMENT, and the element has attributes. - \return Returns amount of attributes of this xml node. */ - virtual int getAttributeCount() const = 0; - - //! Returns name of an attribute. - /** \param idx: Zero based index, should be something between 0 and getAttributeCount()-1. - \return Name of the attribute, 0 if an attribute with this index does not exist. */ - virtual const char_type* getAttributeName(int idx) const = 0; - - //! Returns the value of an attribute. - /** \param idx: Zero based index, should be something between 0 and getAttributeCount()-1. - \return Value of the attribute, 0 if an attribute with this index does not exist. */ - virtual const char_type* getAttributeValue(int idx) const = 0; - - //! Returns the value of an attribute. - /** \param name: Name of the attribute. - \return Value of the attribute, 0 if an attribute with this name does not exist. */ - virtual const char_type* getAttributeValue(const char_type* name) const = 0; - - //! Returns the value of an attribute in a safe way. - /** Like getAttributeValue(), but does not - return 0 if the attribute does not exist. An empty string ("") is returned then. - \param name: Name of the attribute. - \return Value of the attribute, and "" if an attribute with this name does not exist */ - virtual const char_type* getAttributeValueSafe(const char_type* name) const = 0; - - //! Returns the value of an attribute as integer. - /** \param name Name of the attribute. - \return Value of the attribute as integer, and 0 if an attribute with this name does not exist or - the value could not be interpreted as integer. */ - virtual int getAttributeValueAsInt(const char_type* name) const = 0; - - //! Returns the value of an attribute as integer. - /** \param idx: Zero based index, should be something between 0 and getAttributeCount()-1. - \return Value of the attribute as integer, and 0 if an attribute with this index does not exist or - the value could not be interpreted as integer. */ - virtual int getAttributeValueAsInt(int idx) const = 0; - - //! Returns the value of an attribute as float. - /** \param name: Name of the attribute. - \return Value of the attribute as float, and 0 if an attribute with this name does not exist or - the value could not be interpreted as float. */ - virtual float getAttributeValueAsFloat(const char_type* name) const = 0; - - //! Returns the value of an attribute as float. - /** \param idx: Zero based index, should be something between 0 and getAttributeCount()-1. - \return Value of the attribute as float, and 0 if an attribute with this index does not exist or - the value could not be interpreted as float. */ - virtual float getAttributeValueAsFloat(int idx) const = 0; - - //! Returns the name of the current node. - /** Only non null, if the node type is EXN_ELEMENT. - \return Name of the current node or 0 if the node has no name. */ - virtual const char_type* getNodeName() const = 0; - - //! Returns data of the current node. - /** Only non null if the node has some - data and it is of type EXN_TEXT or EXN_UNKNOWN. */ - virtual const char_type* getNodeData() const = 0; - - //! Returns if an element is an empty element, like - virtual bool isEmptyElement() const = 0; - - //! Returns format of the source xml file. - /** It is not necessary to use - this method because the parser will convert the input file format - to the format wanted by the user when creating the parser. This - method is useful to get/display additional informations. */ - virtual ETEXT_FORMAT getSourceFormat() const = 0; - - //! Returns format of the strings returned by the parser. - /** This will be UTF8 for example when you created a parser with - IrrXMLReaderUTF8() and UTF32 when it has been created using - IrrXMLReaderUTF32. It should not be necessary to call this - method and only exists for informational purposes. */ - virtual ETEXT_FORMAT getParserFormat() const = 0; - }; - - - //! defines the utf-16 type. - /** Not using wchar_t for this because - wchar_t has 16 bit on windows and 32 bit on other operating systems. */ - typedef unsigned short char16; - - //! defines the utf-32 type. - /** Not using wchar_t for this because - wchar_t has 16 bit on windows and 32 bit on other operating systems. */ - typedef unsigned long char32; - - //! A UTF-8 or ASCII character xml parser. - /** This means that all character data will be returned in 8 bit ASCII or UTF-8 by this parser. - The file to read can be in any format, it will be converted to UTF-8 if it is not - in this format. - Create an instance of this with createIrrXMLReader(); - See IIrrXMLReader for description on how to use it. */ - typedef IIrrXMLReader IrrXMLReader; - - //! A UTF-16 xml parser. - /** This means that all character data will be returned in UTF-16 by this parser. - The file to read can be in any format, it will be converted to UTF-16 if it is not - in this format. - Create an instance of this with createIrrXMLReaderUTF16(); - See IIrrXMLReader for description on how to use it. */ - typedef IIrrXMLReader IrrXMLReaderUTF16; - - //! A UTF-32 xml parser. - /** This means that all character data will be returned in UTF-32 by this parser. - The file to read can be in any format, it will be converted to UTF-32 if it is not - in this format. - Create an instance of this with createIrrXMLReaderUTF32(); - See IIrrXMLReader for description on how to use it. */ - typedef IIrrXMLReader IrrXMLReaderUTF32; - - - //! Creates an instance of an UFT-8 or ASCII character xml parser. - /** This means that all character data will be returned in 8 bit ASCII or UTF-8. - The file to read can be in any format, it will be converted to UTF-8 if it is not in this format. - If you are using the Irrlicht Engine, it is better not to use this function but - IFileSystem::createXMLReaderUTF8() instead. - \param filename: Name of file to be opened. - \return Returns a pointer to the created xml parser. This pointer should be - deleted using 'delete' after no longer needed. Returns 0 if an error occured - and the file could not be opened. */ - IrrXMLReader* createIrrXMLReader(const char* filename); - - //! Creates an instance of an UFT-8 or ASCII character xml parser. - /** This means that all character data will be returned in 8 bit ASCII or UTF-8. The file to read can - be in any format, it will be converted to UTF-8 if it is not in this format. - If you are using the Irrlicht Engine, it is better not to use this function but - IFileSystem::createXMLReaderUTF8() instead. - \param file: Pointer to opened file, must have been opened in binary mode, e.g. - using fopen("foo.bar", "wb"); The file will not be closed after it has been read. - \return Returns a pointer to the created xml parser. This pointer should be - deleted using 'delete' after no longer needed. Returns 0 if an error occured - and the file could not be opened. */ - IrrXMLReader* createIrrXMLReader(FILE* file); - - //! Creates an instance of an UFT-8 or ASCII character xml parser. - /** This means that all character data will be returned in 8 bit ASCII or UTF-8. The file to read can - be in any format, it will be converted to UTF-8 if it is not in this format. - If you are using the Irrlicht Engine, it is better not to use this function but - IFileSystem::createXMLReaderUTF8() instead. - \param callback: Callback for file read abstraction. Implement your own - callback to make the xml parser read in other things than just files. See - IFileReadCallBack for more information about this. - \return Returns a pointer to the created xml parser. This pointer should be - deleted using 'delete' after no longer needed. Returns 0 if an error occured - and the file could not be opened. */ - IrrXMLReader* createIrrXMLReader(IFileReadCallBack* callback); - - //! Creates an instance of an UFT-16 xml parser. - /** This means that - all character data will be returned in UTF-16. The file to read can - be in any format, it will be converted to UTF-16 if it is not in this format. - If you are using the Irrlicht Engine, it is better not to use this function but - IFileSystem::createXMLReader() instead. - \param filename: Name of file to be opened. - \return Returns a pointer to the created xml parser. This pointer should be - deleted using 'delete' after no longer needed. Returns 0 if an error occured - and the file could not be opened. */ - IrrXMLReaderUTF16* createIrrXMLReaderUTF16(const char* filename); - - //! Creates an instance of an UFT-16 xml parser. - /** This means that all character data will be returned in UTF-16. The file to read can - be in any format, it will be converted to UTF-16 if it is not in this format. - If you are using the Irrlicht Engine, it is better not to use this function but - IFileSystem::createXMLReader() instead. - \param file: Pointer to opened file, must have been opened in binary mode, e.g. - using fopen("foo.bar", "wb"); The file will not be closed after it has been read. - \return Returns a pointer to the created xml parser. This pointer should be - deleted using 'delete' after no longer needed. Returns 0 if an error occured - and the file could not be opened. */ - IrrXMLReaderUTF16* createIrrXMLReaderUTF16(FILE* file); - - //! Creates an instance of an UFT-16 xml parser. - /** This means that all character data will be returned in UTF-16. The file to read can - be in any format, it will be converted to UTF-16 if it is not in this format. - If you are using the Irrlicht Engine, it is better not to use this function but - IFileSystem::createXMLReader() instead. - \param callback: Callback for file read abstraction. Implement your own - callback to make the xml parser read in other things than just files. See - IFileReadCallBack for more information about this. - \return Returns a pointer to the created xml parser. This pointer should be - deleted using 'delete' after no longer needed. Returns 0 if an error occured - and the file could not be opened. */ - IrrXMLReaderUTF16* createIrrXMLReaderUTF16(IFileReadCallBack* callback); - - - //! Creates an instance of an UFT-32 xml parser. - /** This means that all character data will be returned in UTF-32. The file to read can - be in any format, it will be converted to UTF-32 if it is not in this format. - If you are using the Irrlicht Engine, it is better not to use this function but - IFileSystem::createXMLReader() instead. - \param filename: Name of file to be opened. - \return Returns a pointer to the created xml parser. This pointer should be - deleted using 'delete' after no longer needed. Returns 0 if an error occured - and the file could not be opened. */ - IrrXMLReaderUTF32* createIrrXMLReaderUTF32(const char* filename); - - //! Creates an instance of an UFT-32 xml parser. - /** This means that all character data will be returned in UTF-32. The file to read can - be in any format, it will be converted to UTF-32 if it is not in this format. - if you are using the Irrlicht Engine, it is better not to use this function but - IFileSystem::createXMLReader() instead. - \param file: Pointer to opened file, must have been opened in binary mode, e.g. - using fopen("foo.bar", "wb"); The file will not be closed after it has been read. - \return Returns a pointer to the created xml parser. This pointer should be - deleted using 'delete' after no longer needed. Returns 0 if an error occured - and the file could not be opened. */ - IrrXMLReaderUTF32* createIrrXMLReaderUTF32(FILE* file); - - //! Creates an instance of an UFT-32 xml parser. - /** This means that - all character data will be returned in UTF-32. The file to read can - be in any format, it will be converted to UTF-32 if it is not in this format. - If you are using the Irrlicht Engine, it is better not to use this function but - IFileSystem::createXMLReader() instead. - \param callback: Callback for file read abstraction. Implement your own - callback to make the xml parser read in other things than just files. See - IFileReadCallBack for more information about this. - \return Returns a pointer to the created xml parser. This pointer should be - deleted using 'delete' after no longer needed. Returns 0 if an error occured - and the file could not be opened. */ - IrrXMLReaderUTF32* createIrrXMLReaderUTF32(IFileReadCallBack* callback); - - - /*! \file irrxml.h - \brief Header file of the irrXML, the Irrlicht XML parser. - - This file includes everything needed for using irrXML, - the XML parser of the Irrlicht Engine. To use irrXML, - you only need to include this file in your project: - - \code - #include - \endcode - - It is also common to use the two namespaces in which irrXML is included, - directly after #including irrXML.h: - - \code - #include - using namespace irr; - using namespace io; - \endcode - */ - -} // end namespace io -} // end namespace irr - -#endif // __IRR_XML_H_INCLUDED__ - +// Copyright (C) 2002-2005 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine" and the "irrXML" project. +// For conditions of distribution and use, see copyright notice in irrlicht.h and/or irrXML.h + +#ifndef __IRR_XML_H_INCLUDED__ +#define __IRR_XML_H_INCLUDED__ + +#include + +/** \mainpage irrXML 1.2 API documentation +
+ + \section intro Introduction + + Welcome to the irrXML API documentation. + Here you'll find any information you'll need to develop applications with + irrXML. If you look for a tutorial on how to start, take a look at the \ref irrxmlexample, + at the homepage of irrXML at xml.irrlicht3d.org + or into the SDK in the directory \example. + + irrXML is intended to be a high speed and easy-to-use XML Parser for C++, and + this documentation is an important part of it. If you have any questions or + suggestions, just send a email to the author of the engine, Nikolaus Gebhardt + (niko (at) irrlicht3d.org). For more informations about this parser, see \ref history. + + \section features Features + + irrXML provides forward-only, read-only + access to a stream of non validated XML data. It was fully implemented by + Nikolaus Gebhardt. Its current features are: + + - It it fast as lighting and has very low memory usage. It was + developed with the intention of being used in 3D games, as it already has been. + - irrXML is very small: It only consists of 60 KB of code and can be added easily + to your existing project. + - Of course, it is platform independent and works with lots of compilers. + - It is able to parse ASCII, UTF-8, UTF-16 and UTF-32 text files, both in + little and big endian format. + - Independent of the input file format, the parser can return all strings in ASCII, UTF-8, + UTF-16 and UTF-32 format. + - With its optional file access abstraction it has the advantage that it can read not + only from files but from any type of data (memory, network, ...). For example when + used with the Irrlicht Engine, it directly reads from compressed .zip files. + - Just like the Irrlicht Engine for which it was originally created, it is extremely easy + to use. + - It has no external dependencies, it does not even need the STL. + + Although irrXML has some strenghts, it currently also has the following limitations: + + - The input xml file is not validated and assumed to be correct. + + \section irrxmlexample Example + + The following code demonstrates the basic usage of irrXML. A simple xml + file like this is parsed: + \code + + + + + + Welcome to the Mesh Viewer of the "Irrlicht Engine". + + + \endcode + + The code for parsing this file would look like this: + \code + #include + using namespace irr; // irrXML is located in the namespace irr::io + using namespace io; + + #include // we use STL strings to store data in this example + + void main() + { + // create the reader using one of the factory functions + + IrrXMLReader* xml = createIrrXMLReader("config.xml"); + + // strings for storing the data we want to get out of the file + std::string modelFile; + std::string messageText; + std::string caption; + + // parse the file until end reached + + while(xml && xml->read()) + { + switch(xml->getNodeType()) + { + case EXN_TEXT: + // in this xml file, the only text which occurs is the messageText + messageText = xml->getNodeData(); + break; + case EXN_ELEMENT: + { + if (!strcmp("model", xml->getNodeName())) + modelFile = xml->getAttributeValue("file"); + else + if (!strcmp("messageText", xml->getNodeName())) + caption = xml->getAttributeValue("caption"); + } + break; + } + } + + // delete the xml parser after usage + delete xml; + } + \endcode + + \section howto How to use + + Simply add the source files in the /src directory of irrXML to your project. Done. + + \section license License + + The irrXML license is based on the zlib license. Basicly, this means you can do with + irrXML whatever you want: + + Copyright (C) 2002-2005 Nikolaus Gebhardt + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source distribution. + + \section history History + + As lots of references in this documentation and the source show, this xml + parser has originally been a part of the + Irrlicht Engine. But because + the parser has become very useful with the latest release, people asked for a + separate version of it, to be able to use it in non Irrlicht projects. With + irrXML 1.0, this has now been done. +*/ + +namespace irr +{ +namespace io +{ + //! Enumeration of all supported source text file formats + enum ETEXT_FORMAT + { + //! ASCII, file without byte order mark, or not a text file + ETF_ASCII, + + //! UTF-8 format + ETF_UTF8, + + //! UTF-16 format, big endian + ETF_UTF16_BE, + + //! UTF-16 format, little endian + ETF_UTF16_LE, + + //! UTF-32 format, big endian + ETF_UTF32_BE, + + //! UTF-32 format, little endian + ETF_UTF32_LE + }; + + + //! Enumeration for all xml nodes which are parsed by IrrXMLReader + enum EXML_NODE + { + //! No xml node. This is usually the node if you did not read anything yet. + EXN_NONE, + + //! A xml element, like + EXN_ELEMENT, + + //! End of an xml element, like + EXN_ELEMENT_END, + + //! Text within a xml element: this is the text. + EXN_TEXT, + + //! An xml comment like <!-- I am a comment --> or a DTD definition. + EXN_COMMENT, + + //! An xml cdata section like <![CDATA[ this is some CDATA ]]> + EXN_CDATA, + + //! Unknown element. + EXN_UNKNOWN + }; + + //! Callback class for file read abstraction. + /** With this, it is possible to make the xml parser read in other things + than just files. The Irrlicht engine is using this for example to + read xml from compressed .zip files. To make the parser read in + any other data, derive a class from this interface, implement the + two methods to read your data and give a pointer to an instance of + your implementation when calling createIrrXMLReader(), + createIrrXMLReaderUTF16() or createIrrXMLReaderUTF32() */ + class IFileReadCallBack + { + public: + + //! virtual destructor + virtual ~IFileReadCallBack() {}; + + //! Reads an amount of bytes from the file. + /** \param buffer: Pointer to buffer where to read bytes will be written to. + \param sizeToRead: Amount of bytes to read from the file. + \return Returns how much bytes were read. */ + virtual int read(void* buffer, int sizeToRead) = 0; + + //! Returns size of file in bytes + virtual int getSize() = 0; + }; + + //! Empty class to be used as parent class for IrrXMLReader. + /** If you need another class as base class for the xml reader, you can do this by creating + the reader using for example new CXMLReaderImpl(yourcallback); + The Irrlicht Engine for example needs IUnknown as base class for every object to + let it automaticly reference countend, hence it replaces IXMLBase with IUnknown. + See irrXML.cpp on how this can be done in detail. */ + class IXMLBase + { + }; + + //! Interface providing easy read access to a XML file. + /** You can create an instance of this reader using one of the factory functions + createIrrXMLReader(), createIrrXMLReaderUTF16() and createIrrXMLReaderUTF32(). + If using the parser from the Irrlicht Engine, please use IFileSystem::createXMLReader() + instead. + For a detailed intro how to use the parser, see \ref irrxmlexample and \ref features. + + The typical usage of this parser looks like this: + \code + #include + using namespace irr; // irrXML is located in the namespace irr::io + using namespace io; + + void main() + { + // create the reader using one of the factory functions + IrrXMLReader* xml = createIrrXMLReader("config.xml"); + + if (xml == 0) + return; // file could not be opened + + // parse the file until end reached + while(xml->read()) + { + // based on xml->getNodeType(), do something. + } + + // delete the xml parser after usage + delete xml; + } + \endcode + See \ref irrxmlexample for a more detailed example. + */ + template + class IIrrXMLReader : public super_class + { + public: + + //! Destructor + virtual ~IIrrXMLReader() {}; + + //! Reads forward to the next xml node. + /** \return Returns false, if there was no further node. */ + virtual bool read() = 0; + + //! Returns the type of the current XML node. + virtual EXML_NODE getNodeType() const = 0; + + //! Returns attribute count of the current XML node. + /** This is usually + non null if the current node is EXN_ELEMENT, and the element has attributes. + \return Returns amount of attributes of this xml node. */ + virtual int getAttributeCount() const = 0; + + //! Returns name of an attribute. + /** \param idx: Zero based index, should be something between 0 and getAttributeCount()-1. + \return Name of the attribute, 0 if an attribute with this index does not exist. */ + virtual const char_type* getAttributeName(int idx) const = 0; + + //! Returns the value of an attribute. + /** \param idx: Zero based index, should be something between 0 and getAttributeCount()-1. + \return Value of the attribute, 0 if an attribute with this index does not exist. */ + virtual const char_type* getAttributeValue(int idx) const = 0; + + //! Returns the value of an attribute. + /** \param name: Name of the attribute. + \return Value of the attribute, 0 if an attribute with this name does not exist. */ + virtual const char_type* getAttributeValue(const char_type* name) const = 0; + + //! Returns the value of an attribute in a safe way. + /** Like getAttributeValue(), but does not + return 0 if the attribute does not exist. An empty string ("") is returned then. + \param name: Name of the attribute. + \return Value of the attribute, and "" if an attribute with this name does not exist */ + virtual const char_type* getAttributeValueSafe(const char_type* name) const = 0; + + //! Returns the value of an attribute as integer. + /** \param name Name of the attribute. + \return Value of the attribute as integer, and 0 if an attribute with this name does not exist or + the value could not be interpreted as integer. */ + virtual int getAttributeValueAsInt(const char_type* name) const = 0; + + //! Returns the value of an attribute as integer. + /** \param idx: Zero based index, should be something between 0 and getAttributeCount()-1. + \return Value of the attribute as integer, and 0 if an attribute with this index does not exist or + the value could not be interpreted as integer. */ + virtual int getAttributeValueAsInt(int idx) const = 0; + + //! Returns the value of an attribute as float. + /** \param name: Name of the attribute. + \return Value of the attribute as float, and 0 if an attribute with this name does not exist or + the value could not be interpreted as float. */ + virtual float getAttributeValueAsFloat(const char_type* name) const = 0; + + //! Returns the value of an attribute as float. + /** \param idx: Zero based index, should be something between 0 and getAttributeCount()-1. + \return Value of the attribute as float, and 0 if an attribute with this index does not exist or + the value could not be interpreted as float. */ + virtual float getAttributeValueAsFloat(int idx) const = 0; + + //! Returns the name of the current node. + /** Only non null, if the node type is EXN_ELEMENT. + \return Name of the current node or 0 if the node has no name. */ + virtual const char_type* getNodeName() const = 0; + + //! Returns data of the current node. + /** Only non null if the node has some + data and it is of type EXN_TEXT or EXN_UNKNOWN. */ + virtual const char_type* getNodeData() const = 0; + + //! Returns if an element is an empty element, like + virtual bool isEmptyElement() const = 0; + + //! Returns format of the source xml file. + /** It is not necessary to use + this method because the parser will convert the input file format + to the format wanted by the user when creating the parser. This + method is useful to get/display additional informations. */ + virtual ETEXT_FORMAT getSourceFormat() const = 0; + + //! Returns format of the strings returned by the parser. + /** This will be UTF8 for example when you created a parser with + IrrXMLReaderUTF8() and UTF32 when it has been created using + IrrXMLReaderUTF32. It should not be necessary to call this + method and only exists for informational purposes. */ + virtual ETEXT_FORMAT getParserFormat() const = 0; + }; + + + //! defines the utf-16 type. + /** Not using wchar_t for this because + wchar_t has 16 bit on windows and 32 bit on other operating systems. */ + typedef unsigned short char16; + + //! defines the utf-32 type. + /** Not using wchar_t for this because + wchar_t has 16 bit on windows and 32 bit on other operating systems. */ + typedef unsigned long char32; + + //! A UTF-8 or ASCII character xml parser. + /** This means that all character data will be returned in 8 bit ASCII or UTF-8 by this parser. + The file to read can be in any format, it will be converted to UTF-8 if it is not + in this format. + Create an instance of this with createIrrXMLReader(); + See IIrrXMLReader for description on how to use it. */ + typedef IIrrXMLReader IrrXMLReader; + + //! A UTF-16 xml parser. + /** This means that all character data will be returned in UTF-16 by this parser. + The file to read can be in any format, it will be converted to UTF-16 if it is not + in this format. + Create an instance of this with createIrrXMLReaderUTF16(); + See IIrrXMLReader for description on how to use it. */ + typedef IIrrXMLReader IrrXMLReaderUTF16; + + //! A UTF-32 xml parser. + /** This means that all character data will be returned in UTF-32 by this parser. + The file to read can be in any format, it will be converted to UTF-32 if it is not + in this format. + Create an instance of this with createIrrXMLReaderUTF32(); + See IIrrXMLReader for description on how to use it. */ + typedef IIrrXMLReader IrrXMLReaderUTF32; + + + //! Creates an instance of an UFT-8 or ASCII character xml parser. + /** This means that all character data will be returned in 8 bit ASCII or UTF-8. + The file to read can be in any format, it will be converted to UTF-8 if it is not in this format. + If you are using the Irrlicht Engine, it is better not to use this function but + IFileSystem::createXMLReaderUTF8() instead. + \param filename: Name of file to be opened. + \return Returns a pointer to the created xml parser. This pointer should be + deleted using 'delete' after no longer needed. Returns 0 if an error occured + and the file could not be opened. */ + IrrXMLReader* createIrrXMLReader(const char* filename); + + //! Creates an instance of an UFT-8 or ASCII character xml parser. + /** This means that all character data will be returned in 8 bit ASCII or UTF-8. The file to read can + be in any format, it will be converted to UTF-8 if it is not in this format. + If you are using the Irrlicht Engine, it is better not to use this function but + IFileSystem::createXMLReaderUTF8() instead. + \param file: Pointer to opened file, must have been opened in binary mode, e.g. + using fopen("foo.bar", "wb"); The file will not be closed after it has been read. + \return Returns a pointer to the created xml parser. This pointer should be + deleted using 'delete' after no longer needed. Returns 0 if an error occured + and the file could not be opened. */ + IrrXMLReader* createIrrXMLReader(FILE* file); + + //! Creates an instance of an UFT-8 or ASCII character xml parser. + /** This means that all character data will be returned in 8 bit ASCII or UTF-8. The file to read can + be in any format, it will be converted to UTF-8 if it is not in this format. + If you are using the Irrlicht Engine, it is better not to use this function but + IFileSystem::createXMLReaderUTF8() instead. + \param callback: Callback for file read abstraction. Implement your own + callback to make the xml parser read in other things than just files. See + IFileReadCallBack for more information about this. + \return Returns a pointer to the created xml parser. This pointer should be + deleted using 'delete' after no longer needed. Returns 0 if an error occured + and the file could not be opened. */ + IrrXMLReader* createIrrXMLReader(IFileReadCallBack* callback); + + //! Creates an instance of an UFT-16 xml parser. + /** This means that + all character data will be returned in UTF-16. The file to read can + be in any format, it will be converted to UTF-16 if it is not in this format. + If you are using the Irrlicht Engine, it is better not to use this function but + IFileSystem::createXMLReader() instead. + \param filename: Name of file to be opened. + \return Returns a pointer to the created xml parser. This pointer should be + deleted using 'delete' after no longer needed. Returns 0 if an error occured + and the file could not be opened. */ + IrrXMLReaderUTF16* createIrrXMLReaderUTF16(const char* filename); + + //! Creates an instance of an UFT-16 xml parser. + /** This means that all character data will be returned in UTF-16. The file to read can + be in any format, it will be converted to UTF-16 if it is not in this format. + If you are using the Irrlicht Engine, it is better not to use this function but + IFileSystem::createXMLReader() instead. + \param file: Pointer to opened file, must have been opened in binary mode, e.g. + using fopen("foo.bar", "wb"); The file will not be closed after it has been read. + \return Returns a pointer to the created xml parser. This pointer should be + deleted using 'delete' after no longer needed. Returns 0 if an error occured + and the file could not be opened. */ + IrrXMLReaderUTF16* createIrrXMLReaderUTF16(FILE* file); + + //! Creates an instance of an UFT-16 xml parser. + /** This means that all character data will be returned in UTF-16. The file to read can + be in any format, it will be converted to UTF-16 if it is not in this format. + If you are using the Irrlicht Engine, it is better not to use this function but + IFileSystem::createXMLReader() instead. + \param callback: Callback for file read abstraction. Implement your own + callback to make the xml parser read in other things than just files. See + IFileReadCallBack for more information about this. + \return Returns a pointer to the created xml parser. This pointer should be + deleted using 'delete' after no longer needed. Returns 0 if an error occured + and the file could not be opened. */ + IrrXMLReaderUTF16* createIrrXMLReaderUTF16(IFileReadCallBack* callback); + + + //! Creates an instance of an UFT-32 xml parser. + /** This means that all character data will be returned in UTF-32. The file to read can + be in any format, it will be converted to UTF-32 if it is not in this format. + If you are using the Irrlicht Engine, it is better not to use this function but + IFileSystem::createXMLReader() instead. + \param filename: Name of file to be opened. + \return Returns a pointer to the created xml parser. This pointer should be + deleted using 'delete' after no longer needed. Returns 0 if an error occured + and the file could not be opened. */ + IrrXMLReaderUTF32* createIrrXMLReaderUTF32(const char* filename); + + //! Creates an instance of an UFT-32 xml parser. + /** This means that all character data will be returned in UTF-32. The file to read can + be in any format, it will be converted to UTF-32 if it is not in this format. + if you are using the Irrlicht Engine, it is better not to use this function but + IFileSystem::createXMLReader() instead. + \param file: Pointer to opened file, must have been opened in binary mode, e.g. + using fopen("foo.bar", "wb"); The file will not be closed after it has been read. + \return Returns a pointer to the created xml parser. This pointer should be + deleted using 'delete' after no longer needed. Returns 0 if an error occured + and the file could not be opened. */ + IrrXMLReaderUTF32* createIrrXMLReaderUTF32(FILE* file); + + //! Creates an instance of an UFT-32 xml parser. + /** This means that + all character data will be returned in UTF-32. The file to read can + be in any format, it will be converted to UTF-32 if it is not in this format. + If you are using the Irrlicht Engine, it is better not to use this function but + IFileSystem::createXMLReader() instead. + \param callback: Callback for file read abstraction. Implement your own + callback to make the xml parser read in other things than just files. See + IFileReadCallBack for more information about this. + \return Returns a pointer to the created xml parser. This pointer should be + deleted using 'delete' after no longer needed. Returns 0 if an error occured + and the file could not be opened. */ + IrrXMLReaderUTF32* createIrrXMLReaderUTF32(IFileReadCallBack* callback); + + + /*! \file irrxml.h + \brief Header file of the irrXML, the Irrlicht XML parser. + + This file includes everything needed for using irrXML, + the XML parser of the Irrlicht Engine. To use irrXML, + you only need to include this file in your project: + + \code + #include + \endcode + + It is also common to use the two namespaces in which irrXML is included, + directly after #including irrXML.h: + + \code + #include + using namespace irr; + using namespace io; + \endcode + */ + +} // end namespace io +} // end namespace irr + +#endif // __IRR_XML_H_INCLUDED__ + diff --git a/contrib/irrXML_note.txt b/contrib/irrXML_note.txt index 403a0dbc6..ff7897ec2 100644 --- a/contrib/irrXML_note.txt +++ b/contrib/irrXML_note.txt @@ -1,6 +1,6 @@ - -IrrXML -Downloaded September 2008 - -- fixed a minor compiler warning (vs 2005, shift too large) -- fixed an issue regarding wchar_t/unsigned short + +IrrXML +Downloaded September 2008 + +- fixed a minor compiler warning (vs 2005, shift too large) +- fixed an issue regarding wchar_t/unsigned short diff --git a/contrib/poly2tri/poly2tri/common/utils.h b/contrib/poly2tri/poly2tri/common/utils.h index e3ed008f3..cb7a7dc01 100644 --- a/contrib/poly2tri/poly2tri/common/utils.h +++ b/contrib/poly2tri/poly2tri/common/utils.h @@ -1,105 +1,105 @@ -/* - * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors - * http://code.google.com/p/poly2tri/ - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Poly2Tri nor the names of its contributors may be - * used to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef UTILS_H -#define UTILS_H - -// Otherwise #defines like M_PI are undeclared under Visual Studio -#define _USE_MATH_DEFINES - -#include -#include - -namespace p2t { - -const double PI_3div4 = 3 * M_PI / 4; -const double EPSILON = 1e-15; - -enum Orientation { CW, CCW, COLLINEAR }; - -/** - * Forumla to calculate signed area
- * Positive if CCW
- * Negative if CW
- * 0 if collinear
- *
- * A[P1,P2,P3]  =  (x1*y2 - y1*x2) + (x2*y3 - y2*x3) + (x3*y1 - y3*x1)
- *              =  (x1-x3)*(y2-y3) - (y1-y3)*(x2-x3)
- * 
- */ -Orientation Orient2d(Point& pa, Point& pb, Point& pc) -{ - double detleft = (pa.x - pc.x) * (pb.y - pc.y); - double detright = (pa.y - pc.y) * (pb.x - pc.x); - double val = detleft - detright; - if (val > -EPSILON && val < EPSILON) { - return COLLINEAR; - } else if (val > 0) { - return CCW; - } - return CW; -} - -bool InScanArea(Point& pa, Point& pb, Point& pc, Point& pd) -{ - double pdx = pd.x; - double pdy = pd.y; - double adx = pa.x - pdx; - double ady = pa.y - pdy; - double bdx = pb.x - pdx; - double bdy = pb.y - pdy; - - double adxbdy = adx * bdy; - double bdxady = bdx * ady; - double oabd = adxbdy - bdxady; - - if (oabd <= EPSILON) { - return false; - } - - double cdx = pc.x - pdx; - double cdy = pc.y - pdy; - - double cdxady = cdx * ady; - double adxcdy = adx * cdy; - double ocad = cdxady - adxcdy; - - if (ocad <= EPSILON) { - return false; - } - - return true; -} - -} - -#endif - +/* + * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors + * http://code.google.com/p/poly2tri/ + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of Poly2Tri nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef UTILS_H +#define UTILS_H + +// Otherwise #defines like M_PI are undeclared under Visual Studio +#define _USE_MATH_DEFINES + +#include +#include + +namespace p2t { + +const double PI_3div4 = 3 * M_PI / 4; +const double EPSILON = 1e-15; + +enum Orientation { CW, CCW, COLLINEAR }; + +/** + * Forumla to calculate signed area
+ * Positive if CCW
+ * Negative if CW
+ * 0 if collinear
+ *
+ * A[P1,P2,P3]  =  (x1*y2 - y1*x2) + (x2*y3 - y2*x3) + (x3*y1 - y3*x1)
+ *              =  (x1-x3)*(y2-y3) - (y1-y3)*(x2-x3)
+ * 
+ */ +Orientation Orient2d(Point& pa, Point& pb, Point& pc) +{ + double detleft = (pa.x - pc.x) * (pb.y - pc.y); + double detright = (pa.y - pc.y) * (pb.x - pc.x); + double val = detleft - detright; + if (val > -EPSILON && val < EPSILON) { + return COLLINEAR; + } else if (val > 0) { + return CCW; + } + return CW; +} + +bool InScanArea(Point& pa, Point& pb, Point& pc, Point& pd) +{ + double pdx = pd.x; + double pdy = pd.y; + double adx = pa.x - pdx; + double ady = pa.y - pdy; + double bdx = pb.x - pdx; + double bdy = pb.y - pdy; + + double adxbdy = adx * bdy; + double bdxady = bdx * ady; + double oabd = adxbdy - bdxady; + + if (oabd <= EPSILON) { + return false; + } + + double cdx = pc.x - pdx; + double cdy = pc.y - pdy; + + double cdxady = cdx * ady; + double adxcdy = adx * cdy; + double ocad = cdxady - adxcdy; + + if (ocad <= EPSILON) { + return false; + } + + return true; +} + +} + +#endif + diff --git a/contrib/poly2tri/poly2tri/sweep/cdt.h b/contrib/poly2tri/poly2tri/sweep/cdt.h index baf6ca7dd..3e6f02408 100644 --- a/contrib/poly2tri/poly2tri/sweep/cdt.h +++ b/contrib/poly2tri/poly2tri/sweep/cdt.h @@ -1,105 +1,105 @@ -/* - * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors - * http://code.google.com/p/poly2tri/ - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Poly2Tri nor the names of its contributors may be - * used to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef CDT_H -#define CDT_H - -#include "advancing_front.h" -#include "sweep_context.h" -#include "sweep.h" - -/** - * - * @author Mason Green - * - */ - -namespace p2t { - -class CDT -{ -public: - - /** - * Constructor - add polyline with non repeating points - * - * @param polyline - */ - CDT(std::vector polyline); - - /** - * Destructor - clean up memory - */ - ~CDT(); - - /** - * Add a hole - * - * @param polyline - */ - void AddHole(std::vector polyline); - - /** - * Add a steiner point - * - * @param point - */ - void AddPoint(Point* point); - - /** - * Triangulate - do this AFTER you've added the polyline, holes, and Steiner points - */ - void Triangulate(); - - /** - * Get CDT triangles - */ - std::vector GetTriangles(); - - /** - * Get triangle map - */ - std::list GetMap(); - - private: - - /** - * Internals - */ - - SweepContext* sweep_context_; - Sweep* sweep_; - -}; - -} - -#endif +/* + * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors + * http://code.google.com/p/poly2tri/ + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of Poly2Tri nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef CDT_H +#define CDT_H + +#include "advancing_front.h" +#include "sweep_context.h" +#include "sweep.h" + +/** + * + * @author Mason Green + * + */ + +namespace p2t { + +class CDT +{ +public: + + /** + * Constructor - add polyline with non repeating points + * + * @param polyline + */ + CDT(std::vector polyline); + + /** + * Destructor - clean up memory + */ + ~CDT(); + + /** + * Add a hole + * + * @param polyline + */ + void AddHole(std::vector polyline); + + /** + * Add a steiner point + * + * @param point + */ + void AddPoint(Point* point); + + /** + * Triangulate - do this AFTER you've added the polyline, holes, and Steiner points + */ + void Triangulate(); + + /** + * Get CDT triangles + */ + std::vector GetTriangles(); + + /** + * Get triangle map + */ + std::list GetMap(); + + private: + + /** + * Internals + */ + + SweepContext* sweep_context_; + Sweep* sweep_; + +}; + +} + +#endif diff --git a/contrib/poly2tri/poly2tri/sweep/sweep_context.h b/contrib/poly2tri/poly2tri/sweep/sweep_context.h index 266408dc2..1010c0e8a 100644 --- a/contrib/poly2tri/poly2tri/sweep/sweep_context.h +++ b/contrib/poly2tri/poly2tri/sweep/sweep_context.h @@ -1,186 +1,186 @@ -/* - * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors - * http://code.google.com/p/poly2tri/ - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Poly2Tri nor the names of its contributors may be - * used to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SWEEP_CONTEXT_H -#define SWEEP_CONTEXT_H - -#include -#include -#include - -namespace p2t { - -// Inital triangle factor, seed triangle will extend 30% of -// PointSet width to both left and right. -const double kAlpha = 0.3; - -struct Point; -class Triangle; -struct Node; -struct Edge; -class AdvancingFront; - -class SweepContext { -public: - -/// Constructor -SweepContext(std::vector polyline); -/// Destructor -~SweepContext(); - -void set_head(Point* p1); - -Point* head(); - -void set_tail(Point* p1); - -Point* tail(); - -int point_count(); - -Node& LocateNode(Point& point); - -void RemoveNode(Node* node); - -void CreateAdvancingFront(std::vector nodes); - -/// Try to map a node to all sides of this triangle that don't have a neighbor -void MapTriangleToNodes(Triangle& t); - -void AddToMap(Triangle* triangle); - -Point* GetPoint(const int& index); - -Point* GetPoints(); - -void RemoveFromMap(Triangle* triangle); - -void AddHole(std::vector polyline); - -void AddPoint(Point* point); - -AdvancingFront* front(); - -void MeshClean(Triangle& triangle); - -std::vector GetTriangles(); +/* + * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors + * http://code.google.com/p/poly2tri/ + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of Poly2Tri nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SWEEP_CONTEXT_H +#define SWEEP_CONTEXT_H + +#include +#include +#include + +namespace p2t { + +// Inital triangle factor, seed triangle will extend 30% of +// PointSet width to both left and right. +const double kAlpha = 0.3; + +struct Point; +class Triangle; +struct Node; +struct Edge; +class AdvancingFront; + +class SweepContext { +public: + +/// Constructor +SweepContext(std::vector polyline); +/// Destructor +~SweepContext(); + +void set_head(Point* p1); + +Point* head(); + +void set_tail(Point* p1); + +Point* tail(); + +int point_count(); + +Node& LocateNode(Point& point); + +void RemoveNode(Node* node); + +void CreateAdvancingFront(std::vector nodes); + +/// Try to map a node to all sides of this triangle that don't have a neighbor +void MapTriangleToNodes(Triangle& t); + +void AddToMap(Triangle* triangle); + +Point* GetPoint(const int& index); + +Point* GetPoints(); + +void RemoveFromMap(Triangle* triangle); + +void AddHole(std::vector polyline); + +void AddPoint(Point* point); + +AdvancingFront* front(); + +void MeshClean(Triangle& triangle); + +std::vector GetTriangles(); std::list GetMap(); - -std::vector edge_list; - -struct Basin { - Node* left_node; - Node* bottom_node; - Node* right_node; - double width; - bool left_highest; - - Basin() : left_node(NULL), bottom_node(NULL), right_node(NULL), width(0.0), left_highest(false) - { - } - - void Clear() - { - left_node = NULL; - bottom_node = NULL; - right_node = NULL; - width = 0.0; - left_highest = false; - } -}; - -struct EdgeEvent { - Edge* constrained_edge; - bool right; - - EdgeEvent() : constrained_edge(NULL), right(false) - { - } -}; - -Basin basin; -EdgeEvent edge_event; - -private: - -friend class Sweep; - -std::vector triangles_; -std::list map_; -std::vector points_; - -// Advancing front -AdvancingFront* front_; -// head point used with advancing front -Point* head_; -// tail point used with advancing front -Point* tail_; - -Node *af_head_, *af_middle_, *af_tail_; - -void InitTriangulation(); -void InitEdges(std::vector polyline); - -}; - -inline AdvancingFront* SweepContext::front() -{ - return front_; -} - -inline int SweepContext::point_count() -{ - return points_.size(); -} - -inline void SweepContext::set_head(Point* p1) -{ - head_ = p1; -} - -inline Point* SweepContext::head() -{ - return head_; -} - -inline void SweepContext::set_tail(Point* p1) -{ - tail_ = p1; -} - -inline Point* SweepContext::tail() -{ - return tail_; -} - -} - -#endif + +std::vector edge_list; + +struct Basin { + Node* left_node; + Node* bottom_node; + Node* right_node; + double width; + bool left_highest; + + Basin() : left_node(NULL), bottom_node(NULL), right_node(NULL), width(0.0), left_highest(false) + { + } + + void Clear() + { + left_node = NULL; + bottom_node = NULL; + right_node = NULL; + width = 0.0; + left_highest = false; + } +}; + +struct EdgeEvent { + Edge* constrained_edge; + bool right; + + EdgeEvent() : constrained_edge(NULL), right(false) + { + } +}; + +Basin basin; +EdgeEvent edge_event; + +private: + +friend class Sweep; + +std::vector triangles_; +std::list map_; +std::vector points_; + +// Advancing front +AdvancingFront* front_; +// head point used with advancing front +Point* head_; +// tail point used with advancing front +Point* tail_; + +Node *af_head_, *af_middle_, *af_tail_; + +void InitTriangulation(); +void InitEdges(std::vector polyline); + +}; + +inline AdvancingFront* SweepContext::front() +{ + return front_; +} + +inline int SweepContext::point_count() +{ + return points_.size(); +} + +inline void SweepContext::set_head(Point* p1) +{ + head_ = p1; +} + +inline Point* SweepContext::head() +{ + return head_; +} + +inline void SweepContext::set_tail(Point* p1) +{ + tail_ = p1; +} + +inline Point* SweepContext::tail() +{ + return tail_; +} + +} + +#endif diff --git a/contrib/poly2tri_patch.txt b/contrib/poly2tri_patch.txt index 33e621b20..e9cca4cec 100644 --- a/contrib/poly2tri_patch.txt +++ b/contrib/poly2tri_patch.txt @@ -1,75 +1,75 @@ -diff -r 5de9623d6a50 poly2tri/common/shapes.h ---- a/poly2tri/common/shapes.h Mon Aug 08 22:26:41 2011 -0400 -+++ b/poly2tri/common/shapes.h Tue Jan 17 02:36:52 2012 +0100 -@@ -35,6 +35,7 @@ - - #include - #include -+#include - #include - #include - -@@ -136,7 +137,9 @@ - p = &p2; - } else if (p1.x == p2.x) { - // Repeat points -- assert(false); -+ // ASSIMP_CHANGE (aramis_acg) -+ throw std::runtime_error("repeat points"); -+ //assert(false); - } - } - -diff -r 5de9623d6a50 poly2tri/sweep/sweep.cc ---- a/poly2tri/sweep/sweep.cc Mon Aug 08 22:26:41 2011 -0400 -+++ b/poly2tri/sweep/sweep.cc Tue Jan 17 02:36:52 2012 +0100 -@@ -113,6 +113,8 @@ - Point* p1 = triangle->PointCCW(point); - Orientation o1 = Orient2d(eq, *p1, ep); - if (o1 == COLLINEAR) { -+ // ASSIMP_CHANGE (aramis_acg) -+ throw std::runtime_error("EdgeEvent - collinear points not supported"); - if( triangle->Contains(&eq, p1)) { - triangle->MarkConstrainedEdge(&eq, p1 ); - // We are modifying the constraint maybe it would be better to -@@ -121,8 +123,8 @@ - triangle = &triangle->NeighborAcross(point); - EdgeEvent( tcx, ep, *p1, triangle, *p1 ); - } else { -+ // ASSIMP_CHANGE (aramis_acg) - std::runtime_error("EdgeEvent - collinear points not supported"); -- assert(0); - } - return; - } -@@ -130,6 +132,9 @@ - Point* p2 = triangle->PointCW(point); - Orientation o2 = Orient2d(eq, *p2, ep); - if (o2 == COLLINEAR) { -+ // ASSIMP_CHANGE (aramis_acg) -+ throw std::runtime_error("EdgeEvent - collinear points not supported"); -+ - if( triangle->Contains(&eq, p2)) { - triangle->MarkConstrainedEdge(&eq, p2 ); - // We are modifying the constraint maybe it would be better to -@@ -138,8 +143,8 @@ - triangle = &triangle->NeighborAcross(point); - EdgeEvent( tcx, ep, *p2, triangle, *p2 ); - } else { -- std::runtime_error("EdgeEvent - collinear points not supported"); -- assert(0); -+ // ASSIMP_CHANGE (aramis_acg) -+ throw std::runtime_error("EdgeEvent - collinear points not supported"); - } - return; - } -@@ -712,7 +717,8 @@ - return *ot.PointCW(op); - } else{ - //throw new RuntimeException("[Unsupported] Opposing point on constrained edge"); -- assert(0); -+ // ASSIMP_CHANGE (aramis_acg) -+ throw std::runtime_error("[Unsupported] Opposing point on constrained edge"); - } - } - +diff -r 5de9623d6a50 poly2tri/common/shapes.h +--- a/poly2tri/common/shapes.h Mon Aug 08 22:26:41 2011 -0400 ++++ b/poly2tri/common/shapes.h Tue Jan 17 02:36:52 2012 +0100 +@@ -35,6 +35,7 @@ + + #include + #include ++#include + #include + #include + +@@ -136,7 +137,9 @@ + p = &p2; + } else if (p1.x == p2.x) { + // Repeat points +- assert(false); ++ // ASSIMP_CHANGE (aramis_acg) ++ throw std::runtime_error("repeat points"); ++ //assert(false); + } + } + +diff -r 5de9623d6a50 poly2tri/sweep/sweep.cc +--- a/poly2tri/sweep/sweep.cc Mon Aug 08 22:26:41 2011 -0400 ++++ b/poly2tri/sweep/sweep.cc Tue Jan 17 02:36:52 2012 +0100 +@@ -113,6 +113,8 @@ + Point* p1 = triangle->PointCCW(point); + Orientation o1 = Orient2d(eq, *p1, ep); + if (o1 == COLLINEAR) { ++ // ASSIMP_CHANGE (aramis_acg) ++ throw std::runtime_error("EdgeEvent - collinear points not supported"); + if( triangle->Contains(&eq, p1)) { + triangle->MarkConstrainedEdge(&eq, p1 ); + // We are modifying the constraint maybe it would be better to +@@ -121,8 +123,8 @@ + triangle = &triangle->NeighborAcross(point); + EdgeEvent( tcx, ep, *p1, triangle, *p1 ); + } else { ++ // ASSIMP_CHANGE (aramis_acg) + std::runtime_error("EdgeEvent - collinear points not supported"); +- assert(0); + } + return; + } +@@ -130,6 +132,9 @@ + Point* p2 = triangle->PointCW(point); + Orientation o2 = Orient2d(eq, *p2, ep); + if (o2 == COLLINEAR) { ++ // ASSIMP_CHANGE (aramis_acg) ++ throw std::runtime_error("EdgeEvent - collinear points not supported"); ++ + if( triangle->Contains(&eq, p2)) { + triangle->MarkConstrainedEdge(&eq, p2 ); + // We are modifying the constraint maybe it would be better to +@@ -138,8 +143,8 @@ + triangle = &triangle->NeighborAcross(point); + EdgeEvent( tcx, ep, *p2, triangle, *p2 ); + } else { +- std::runtime_error("EdgeEvent - collinear points not supported"); +- assert(0); ++ // ASSIMP_CHANGE (aramis_acg) ++ throw std::runtime_error("EdgeEvent - collinear points not supported"); + } + return; + } +@@ -712,7 +717,8 @@ + return *ot.PointCW(op); + } else{ + //throw new RuntimeException("[Unsupported] Opposing point on constrained edge"); +- assert(0); ++ // ASSIMP_CHANGE (aramis_acg) ++ throw std::runtime_error("[Unsupported] Opposing point on constrained edge"); + } + } + diff --git a/contrib/unzip/crypt.h b/contrib/unzip/crypt.h index f14a628b4..622f4bc2e 100644 --- a/contrib/unzip/crypt.h +++ b/contrib/unzip/crypt.h @@ -1,132 +1,132 @@ -/* crypt.h -- base code for crypt/uncrypt ZIPfile - - - Version 1.01e, February 12th, 2005 - - Copyright (C) 1998-2005 Gilles Vollant - - This code is a modified version of crypting code in Infozip distribution - - The encryption/decryption parts of this source code (as opposed to the - non-echoing password parts) were originally written in Europe. The - whole source package can be freely distributed, including from the USA. - (Prior to January 2000, re-export from the US was a violation of US law.) - - This encryption code is a direct transcription of the algorithm from - Roger Schlafly, described by Phil Katz in the file appnote.txt. This - file (appnote.txt) is distributed with the PKZIP program (even in the - version without encryption capabilities). - - If you don't need crypting in your application, just define symbols - NOCRYPT and NOUNCRYPT. - - This code support the "Traditional PKWARE Encryption". - - The new AES encryption added on Zip format by Winzip (see the page - http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong - Encryption is not supported. -*/ - -#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8)) - -/*********************************************************************** - * Return the next byte in the pseudo-random sequence - */ -static int decrypt_byte(unsigned long* pkeys, const unsigned long* pcrc_32_tab) -{ - unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an - * unpredictable manner on 16-bit systems; not a problem - * with any known compiler so far, though */ - - temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2; - return (int)(((temp * (temp ^ 1)) >> 8) & 0xff); -} - -/*********************************************************************** - * Update the encryption keys with the next byte of plain text - */ -static int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int c) -{ - (*(pkeys+0)) = CRC32((*(pkeys+0)), c); - (*(pkeys+1)) += (*(pkeys+0)) & 0xff; - (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1; - { - register int keyshift = (int)((*(pkeys+1)) >> 24); - (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift); - } - return c; -} - - -/*********************************************************************** - * Initialize the encryption keys and the random header according to - * the given password. - */ -static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned long* pcrc_32_tab) -{ - *(pkeys+0) = 305419896L; - *(pkeys+1) = 591751049L; - *(pkeys+2) = 878082192L; - while (*passwd != '\0') { - update_keys(pkeys,pcrc_32_tab,(int)*passwd); - passwd++; - } -} - -#define zdecode(pkeys,pcrc_32_tab,c) \ - (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab))) - -#define zencode(pkeys,pcrc_32_tab,c,t) \ - (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c)) - -#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED - -#define RAND_HEAD_LEN 12 - /* "last resort" source for second part of crypt seed pattern */ -# ifndef ZCR_SEED2 -# define ZCR_SEED2 3141592654UL /* use PI as default pattern */ -# endif - -static int crypthead(passwd, buf, bufSize, pkeys, pcrc_32_tab, crcForCrypting) - const char *passwd; /* password string */ - unsigned char *buf; /* where to write header */ - int bufSize; - unsigned long* pkeys; - const unsigned long* pcrc_32_tab; - unsigned long crcForCrypting; -{ - int n; /* index in random header */ - int t; /* temporary */ - int c; /* random byte */ - unsigned char header[RAND_HEAD_LEN-2]; /* random header */ - static unsigned calls = 0; /* ensure different random header each time */ - - if (bufSize> 7) & 0xff; - header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t); - } - /* Encrypt random header (last two bytes is high word of crc) */ - init_keys(passwd, pkeys, pcrc_32_tab); - for (n = 0; n < RAND_HEAD_LEN-2; n++) - { - buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t); - } - buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t); - buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t); - return n; -} - -#endif +/* crypt.h -- base code for crypt/uncrypt ZIPfile + + + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant + + This code is a modified version of crypting code in Infozip distribution + + The encryption/decryption parts of this source code (as opposed to the + non-echoing password parts) were originally written in Europe. The + whole source package can be freely distributed, including from the USA. + (Prior to January 2000, re-export from the US was a violation of US law.) + + This encryption code is a direct transcription of the algorithm from + Roger Schlafly, described by Phil Katz in the file appnote.txt. This + file (appnote.txt) is distributed with the PKZIP program (even in the + version without encryption capabilities). + + If you don't need crypting in your application, just define symbols + NOCRYPT and NOUNCRYPT. + + This code support the "Traditional PKWARE Encryption". + + The new AES encryption added on Zip format by Winzip (see the page + http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong + Encryption is not supported. +*/ + +#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8)) + +/*********************************************************************** + * Return the next byte in the pseudo-random sequence + */ +static int decrypt_byte(unsigned long* pkeys, const unsigned long* pcrc_32_tab) +{ + unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an + * unpredictable manner on 16-bit systems; not a problem + * with any known compiler so far, though */ + + temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2; + return (int)(((temp * (temp ^ 1)) >> 8) & 0xff); +} + +/*********************************************************************** + * Update the encryption keys with the next byte of plain text + */ +static int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int c) +{ + (*(pkeys+0)) = CRC32((*(pkeys+0)), c); + (*(pkeys+1)) += (*(pkeys+0)) & 0xff; + (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1; + { + register int keyshift = (int)((*(pkeys+1)) >> 24); + (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift); + } + return c; +} + + +/*********************************************************************** + * Initialize the encryption keys and the random header according to + * the given password. + */ +static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned long* pcrc_32_tab) +{ + *(pkeys+0) = 305419896L; + *(pkeys+1) = 591751049L; + *(pkeys+2) = 878082192L; + while (*passwd != '\0') { + update_keys(pkeys,pcrc_32_tab,(int)*passwd); + passwd++; + } +} + +#define zdecode(pkeys,pcrc_32_tab,c) \ + (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab))) + +#define zencode(pkeys,pcrc_32_tab,c,t) \ + (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c)) + +#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED + +#define RAND_HEAD_LEN 12 + /* "last resort" source for second part of crypt seed pattern */ +# ifndef ZCR_SEED2 +# define ZCR_SEED2 3141592654UL /* use PI as default pattern */ +# endif + +static int crypthead(passwd, buf, bufSize, pkeys, pcrc_32_tab, crcForCrypting) + const char *passwd; /* password string */ + unsigned char *buf; /* where to write header */ + int bufSize; + unsigned long* pkeys; + const unsigned long* pcrc_32_tab; + unsigned long crcForCrypting; +{ + int n; /* index in random header */ + int t; /* temporary */ + int c; /* random byte */ + unsigned char header[RAND_HEAD_LEN-2]; /* random header */ + static unsigned calls = 0; /* ensure different random header each time */ + + if (bufSize> 7) & 0xff; + header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t); + } + /* Encrypt random header (last two bytes is high word of crc) */ + init_keys(passwd, pkeys, pcrc_32_tab); + for (n = 0; n < RAND_HEAD_LEN-2; n++) + { + buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t); + } + buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t); + buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t); + return n; +} + +#endif diff --git a/contrib/unzip/ioapi.c b/contrib/unzip/ioapi.c index 44a9e11a3..b7200df75 100644 --- a/contrib/unzip/ioapi.c +++ b/contrib/unzip/ioapi.c @@ -1,181 +1,181 @@ -/* ioapi.c -- IO base function header for compress/uncompress .zip - files using zlib + zip or unzip API - - Version 1.01e, February 12th, 2005 - - Copyright (C) 1998-2005 Gilles Vollant -*/ - -#include -#include -#include - -# ifdef ASSIMP_BUILD_NO_OWN_ZLIB -# include -# else -# include "../zlib/zlib.h" -# endif -#include "ioapi.h" - - - -/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ - -#ifndef SEEK_CUR -#define SEEK_CUR 1 -#endif - -#ifndef SEEK_END -#define SEEK_END 2 -#endif - -#ifndef SEEK_SET -#define SEEK_SET 0 -#endif - -voidpf ZCALLBACK fopen_file_func ( - voidpf opaque, - const char* filename, - int mode); - -uLong ZCALLBACK fread_file_func ( - voidpf opaque, - voidpf stream, - void* buf, - uLong size); - -uLong ZCALLBACK fwrite_file_func ( - voidpf opaque, - voidpf stream, - const void* buf, - uLong size); - -long ZCALLBACK ftell_file_func ( - voidpf opaque, - voidpf stream); - -long ZCALLBACK fseek_file_func ( - voidpf opaque, - voidpf stream, - uLong offset, - int origin); - -int ZCALLBACK fclose_file_func ( - voidpf opaque, - voidpf stream); - -int ZCALLBACK ferror_file_func ( - voidpf opaque, - voidpf stream); - - -voidpf ZCALLBACK fopen_file_func (opaque, filename, mode) - voidpf opaque; - const char* filename; - int mode; -{ - FILE* file = NULL; - const char* mode_fopen = NULL; - if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) - mode_fopen = "rb"; - else - if (mode & ZLIB_FILEFUNC_MODE_EXISTING) - mode_fopen = "r+b"; - else - if (mode & ZLIB_FILEFUNC_MODE_CREATE) - mode_fopen = "wb"; - - if ((filename!=NULL) && (mode_fopen != NULL)) - file = fopen(filename, mode_fopen); - return file; -} - - -uLong ZCALLBACK fread_file_func (opaque, stream, buf, size) - voidpf opaque; - voidpf stream; - void* buf; - uLong size; -{ - uLong ret; - ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream); - return ret; -} - - -uLong ZCALLBACK fwrite_file_func (opaque, stream, buf, size) - voidpf opaque; - voidpf stream; - const void* buf; - uLong size; -{ - uLong ret; - ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream); - return ret; -} - -long ZCALLBACK ftell_file_func (opaque, stream) - voidpf opaque; - voidpf stream; -{ - long ret; - ret = ftell((FILE *)stream); - return ret; -} - -long ZCALLBACK fseek_file_func (opaque, stream, offset, origin) - voidpf opaque; - voidpf stream; - uLong offset; - int origin; -{ - int fseek_origin=0; - long ret; - switch (origin) - { - case ZLIB_FILEFUNC_SEEK_CUR : - fseek_origin = SEEK_CUR; - break; - case ZLIB_FILEFUNC_SEEK_END : - fseek_origin = SEEK_END; - break; - case ZLIB_FILEFUNC_SEEK_SET : - fseek_origin = SEEK_SET; - break; - default: return -1; - } - ret = 0; - fseek((FILE *)stream, offset, fseek_origin); - return ret; -} - -int ZCALLBACK fclose_file_func (opaque, stream) - voidpf opaque; - voidpf stream; -{ - int ret; - ret = fclose((FILE *)stream); - return ret; -} - -int ZCALLBACK ferror_file_func (opaque, stream) - voidpf opaque; - voidpf stream; -{ - int ret; - ret = ferror((FILE *)stream); - return ret; -} - -void fill_fopen_filefunc (pzlib_filefunc_def) - zlib_filefunc_def* pzlib_filefunc_def; -{ - pzlib_filefunc_def->zopen_file = fopen_file_func; - pzlib_filefunc_def->zread_file = fread_file_func; - pzlib_filefunc_def->zwrite_file = fwrite_file_func; - pzlib_filefunc_def->ztell_file = ftell_file_func; - pzlib_filefunc_def->zseek_file = fseek_file_func; - pzlib_filefunc_def->zclose_file = fclose_file_func; - pzlib_filefunc_def->zerror_file = ferror_file_func; - pzlib_filefunc_def->opaque = NULL; -} +/* ioapi.c -- IO base function header for compress/uncompress .zip + files using zlib + zip or unzip API + + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant +*/ + +#include +#include +#include + +# ifdef ASSIMP_BUILD_NO_OWN_ZLIB +# include +# else +# include "../zlib/zlib.h" +# endif +#include "ioapi.h" + + + +/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ + +#ifndef SEEK_CUR +#define SEEK_CUR 1 +#endif + +#ifndef SEEK_END +#define SEEK_END 2 +#endif + +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif + +voidpf ZCALLBACK fopen_file_func ( + voidpf opaque, + const char* filename, + int mode); + +uLong ZCALLBACK fread_file_func ( + voidpf opaque, + voidpf stream, + void* buf, + uLong size); + +uLong ZCALLBACK fwrite_file_func ( + voidpf opaque, + voidpf stream, + const void* buf, + uLong size); + +long ZCALLBACK ftell_file_func ( + voidpf opaque, + voidpf stream); + +long ZCALLBACK fseek_file_func ( + voidpf opaque, + voidpf stream, + uLong offset, + int origin); + +int ZCALLBACK fclose_file_func ( + voidpf opaque, + voidpf stream); + +int ZCALLBACK ferror_file_func ( + voidpf opaque, + voidpf stream); + + +voidpf ZCALLBACK fopen_file_func (opaque, filename, mode) + voidpf opaque; + const char* filename; + int mode; +{ + FILE* file = NULL; + const char* mode_fopen = NULL; + if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) + mode_fopen = "rb"; + else + if (mode & ZLIB_FILEFUNC_MODE_EXISTING) + mode_fopen = "r+b"; + else + if (mode & ZLIB_FILEFUNC_MODE_CREATE) + mode_fopen = "wb"; + + if ((filename!=NULL) && (mode_fopen != NULL)) + file = fopen(filename, mode_fopen); + return file; +} + + +uLong ZCALLBACK fread_file_func (opaque, stream, buf, size) + voidpf opaque; + voidpf stream; + void* buf; + uLong size; +{ + uLong ret; + ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream); + return ret; +} + + +uLong ZCALLBACK fwrite_file_func (opaque, stream, buf, size) + voidpf opaque; + voidpf stream; + const void* buf; + uLong size; +{ + uLong ret; + ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream); + return ret; +} + +long ZCALLBACK ftell_file_func (opaque, stream) + voidpf opaque; + voidpf stream; +{ + long ret; + ret = ftell((FILE *)stream); + return ret; +} + +long ZCALLBACK fseek_file_func (opaque, stream, offset, origin) + voidpf opaque; + voidpf stream; + uLong offset; + int origin; +{ + int fseek_origin=0; + long ret; + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_CUR : + fseek_origin = SEEK_CUR; + break; + case ZLIB_FILEFUNC_SEEK_END : + fseek_origin = SEEK_END; + break; + case ZLIB_FILEFUNC_SEEK_SET : + fseek_origin = SEEK_SET; + break; + default: return -1; + } + ret = 0; + fseek((FILE *)stream, offset, fseek_origin); + return ret; +} + +int ZCALLBACK fclose_file_func (opaque, stream) + voidpf opaque; + voidpf stream; +{ + int ret; + ret = fclose((FILE *)stream); + return ret; +} + +int ZCALLBACK ferror_file_func (opaque, stream) + voidpf opaque; + voidpf stream; +{ + int ret; + ret = ferror((FILE *)stream); + return ret; +} + +void fill_fopen_filefunc (pzlib_filefunc_def) + zlib_filefunc_def* pzlib_filefunc_def; +{ + pzlib_filefunc_def->zopen_file = fopen_file_func; + pzlib_filefunc_def->zread_file = fread_file_func; + pzlib_filefunc_def->zwrite_file = fwrite_file_func; + pzlib_filefunc_def->ztell_file = ftell_file_func; + pzlib_filefunc_def->zseek_file = fseek_file_func; + pzlib_filefunc_def->zclose_file = fclose_file_func; + pzlib_filefunc_def->zerror_file = ferror_file_func; + pzlib_filefunc_def->opaque = NULL; +} diff --git a/contrib/unzip/ioapi.h b/contrib/unzip/ioapi.h index b12b6c75a..06fdd15e9 100644 --- a/contrib/unzip/ioapi.h +++ b/contrib/unzip/ioapi.h @@ -1,75 +1,75 @@ -/* ioapi.h -- IO base function header for compress/uncompress .zip - files using zlib + zip or unzip API - - Version 1.01e, February 12th, 2005 - - Copyright (C) 1998-2005 Gilles Vollant -*/ - -#ifndef _ZLIBIOAPI_H -#define _ZLIBIOAPI_H - - -#define ZLIB_FILEFUNC_SEEK_CUR (1) -#define ZLIB_FILEFUNC_SEEK_END (2) -#define ZLIB_FILEFUNC_SEEK_SET (0) - -#define ZLIB_FILEFUNC_MODE_READ (1) -#define ZLIB_FILEFUNC_MODE_WRITE (2) -#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3) - -#define ZLIB_FILEFUNC_MODE_EXISTING (4) -#define ZLIB_FILEFUNC_MODE_CREATE (8) - - -#ifndef ZCALLBACK - -#if (defined(WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) -#define ZCALLBACK CALLBACK -#else -#define ZCALLBACK -#endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -typedef voidpf (ZCALLBACK *open_file_func) (voidpf opaque, const char* filename, int mode); -typedef uLong (ZCALLBACK *read_file_func) (voidpf opaque, voidpf stream, void* buf, uLong size); -typedef uLong (ZCALLBACK *write_file_func)(voidpf opaque, voidpf stream, const void* buf, uLong size); -typedef long (ZCALLBACK *tell_file_func) (voidpf opaque, voidpf stream); -typedef long (ZCALLBACK *seek_file_func) (voidpf opaque, voidpf stream, uLong offset, int origin); -typedef int (ZCALLBACK *close_file_func) (voidpf opaque, voidpf stream); -typedef int (ZCALLBACK *testerror_file_func) (voidpf opaque, voidpf stream); - -typedef struct zlib_filefunc_def_s -{ - open_file_func zopen_file; - read_file_func zread_file; - write_file_func zwrite_file; - tell_file_func ztell_file; - seek_file_func zseek_file; - close_file_func zclose_file; - testerror_file_func zerror_file; - voidpf opaque; -} zlib_filefunc_def; - - - -void fill_fopen_filefunc (zlib_filefunc_def* pzlib_filefunc_def); - -#define ZREAD(filefunc,filestream,buf,size) ((*((filefunc).zread_file))((filefunc).opaque,filestream,buf,size)) -#define ZWRITE(filefunc,filestream,buf,size) ((*((filefunc).zwrite_file))((filefunc).opaque,filestream,buf,size)) -#define ZTELL(filefunc,filestream) ((*((filefunc).ztell_file))((filefunc).opaque,filestream)) -#define ZSEEK(filefunc,filestream,pos,mode) ((*((filefunc).zseek_file))((filefunc).opaque,filestream,pos,mode)) -#define ZCLOSE(filefunc,filestream) ((*((filefunc).zclose_file))((filefunc).opaque,filestream)) -#define ZERROR(filefunc,filestream) ((*((filefunc).zerror_file))((filefunc).opaque,filestream)) - - -#ifdef __cplusplus -} -#endif - -#endif - +/* ioapi.h -- IO base function header for compress/uncompress .zip + files using zlib + zip or unzip API + + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant +*/ + +#ifndef _ZLIBIOAPI_H +#define _ZLIBIOAPI_H + + +#define ZLIB_FILEFUNC_SEEK_CUR (1) +#define ZLIB_FILEFUNC_SEEK_END (2) +#define ZLIB_FILEFUNC_SEEK_SET (0) + +#define ZLIB_FILEFUNC_MODE_READ (1) +#define ZLIB_FILEFUNC_MODE_WRITE (2) +#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3) + +#define ZLIB_FILEFUNC_MODE_EXISTING (4) +#define ZLIB_FILEFUNC_MODE_CREATE (8) + + +#ifndef ZCALLBACK + +#if (defined(WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) +#define ZCALLBACK CALLBACK +#else +#define ZCALLBACK +#endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef voidpf (ZCALLBACK *open_file_func) (voidpf opaque, const char* filename, int mode); +typedef uLong (ZCALLBACK *read_file_func) (voidpf opaque, voidpf stream, void* buf, uLong size); +typedef uLong (ZCALLBACK *write_file_func)(voidpf opaque, voidpf stream, const void* buf, uLong size); +typedef long (ZCALLBACK *tell_file_func) (voidpf opaque, voidpf stream); +typedef long (ZCALLBACK *seek_file_func) (voidpf opaque, voidpf stream, uLong offset, int origin); +typedef int (ZCALLBACK *close_file_func) (voidpf opaque, voidpf stream); +typedef int (ZCALLBACK *testerror_file_func) (voidpf opaque, voidpf stream); + +typedef struct zlib_filefunc_def_s +{ + open_file_func zopen_file; + read_file_func zread_file; + write_file_func zwrite_file; + tell_file_func ztell_file; + seek_file_func zseek_file; + close_file_func zclose_file; + testerror_file_func zerror_file; + voidpf opaque; +} zlib_filefunc_def; + + + +void fill_fopen_filefunc (zlib_filefunc_def* pzlib_filefunc_def); + +#define ZREAD(filefunc,filestream,buf,size) ((*((filefunc).zread_file))((filefunc).opaque,filestream,buf,size)) +#define ZWRITE(filefunc,filestream,buf,size) ((*((filefunc).zwrite_file))((filefunc).opaque,filestream,buf,size)) +#define ZTELL(filefunc,filestream) ((*((filefunc).ztell_file))((filefunc).opaque,filestream)) +#define ZSEEK(filefunc,filestream,pos,mode) ((*((filefunc).zseek_file))((filefunc).opaque,filestream,pos,mode)) +#define ZCLOSE(filefunc,filestream) ((*((filefunc).zclose_file))((filefunc).opaque,filestream)) +#define ZERROR(filefunc,filestream) ((*((filefunc).zerror_file))((filefunc).opaque,filestream)) + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/contrib/unzip/unzip.c b/contrib/unzip/unzip.c index e83862a43..af00f7d6f 100644 --- a/contrib/unzip/unzip.c +++ b/contrib/unzip/unzip.c @@ -1,1604 +1,1604 @@ -/* unzip.c -- IO for uncompress .zip files using zlib - Version 1.01e, February 12th, 2005 - - Copyright (C) 1998-2005 Gilles Vollant - - Read unzip.h for more info -*/ - -/* Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of -compatibility with older software. The following is from the original crypt.c. Code -woven in by Terry Thorsen 1/2003. -*/ -/* - Copyright (c) 1990-2000 Info-ZIP. All rights reserved. - - See the accompanying file LICENSE, version 2000-Apr-09 or later - (the contents of which are also included in zip.h) for terms of use. - If, for some reason, all these files are missing, the Info-ZIP license - also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html -*/ -/* - crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h] - - The encryption/decryption parts of this source code (as opposed to the - non-echoing password parts) were originally written in Europe. The - whole source package can be freely distributed, including from the USA. - (Prior to January 2000, re-export from the US was a violation of US law.) - */ - -/* - This encryption code is a direct transcription of the algorithm from - Roger Schlafly, described by Phil Katz in the file appnote.txt. This - file (appnote.txt) is distributed with the PKZIP program (even in the - version without encryption capabilities). - */ - - -#include -#include -#include -#include "./unzip.h" - -#ifdef STDC -# include -# include -# include -#endif -#ifdef NO_ERRNO_H - extern int errno; -#else -# include -#endif - - -#ifndef local -# define local static -#endif -/* compile with -Dlocal if your debugger can't find static symbols */ - - -#ifndef CASESENSITIVITYDEFAULT_NO -# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) -# define CASESENSITIVITYDEFAULT_NO -# endif -#endif - - -#ifndef UNZ_BUFSIZE -#define UNZ_BUFSIZE (16384) -#endif - -#ifndef UNZ_MAXFILENAMEINZIP -#define UNZ_MAXFILENAMEINZIP (256) -#endif - -#ifndef ALLOC -# define ALLOC(size) (malloc(size)) -#endif -#ifndef TRYFREE -# define TRYFREE(p) {if (p) free(p);} -#endif - -#define SIZECENTRALDIRITEM (0x2e) -#define SIZEZIPLOCALHEADER (0x1e) - - - - -const char unz_copyright[] = - " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; - -/* unz_file_info_interntal contain internal info about a file in zipfile*/ -typedef struct unz_file_info_internal_s -{ - uLong offset_curfile;/* relative offset of local header 4 bytes */ -} unz_file_info_internal; - - -/* file_in_zip_read_info_s contain internal information about a file in zipfile, - when reading and decompress it */ -typedef struct -{ - char *read_buffer; /* internal buffer for compressed data */ - z_stream stream; /* zLib stream structure for inflate */ - - uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ - uLong stream_initialised; /* flag set if stream structure is initialised*/ - - uLong offset_local_extrafield;/* offset of the local extra field */ - uInt size_local_extrafield;/* size of the local extra field */ - uLong pos_local_extrafield; /* position in the local extra field in read*/ - - uLong crc32; /* crc32 of all data uncompressed */ - uLong crc32_wait; /* crc32 we must obtain after decompress all */ - uLong rest_read_compressed; /* number of byte to be decompressed */ - uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/ - zlib_filefunc_def z_filefunc; - voidpf filestream; /* io structore of the zipfile */ - uLong compression_method; /* compression method (0==store) */ - uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ - int raw; -} file_in_zip_read_info_s; - - -/* unz_s contain internal information about the zipfile -*/ -typedef struct -{ - zlib_filefunc_def z_filefunc; - voidpf filestream; /* io structore of the zipfile */ - unz_global_info gi; /* public global information */ - uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ - uLong num_file; /* number of the current file in the zipfile*/ - uLong pos_in_central_dir; /* pos of the current file in the central dir*/ - uLong current_file_ok; /* flag about the usability of the current file*/ - uLong central_pos; /* position of the beginning of the central dir*/ - - uLong size_central_dir; /* size of the central directory */ - uLong offset_central_dir; /* offset of start of central directory with - respect to the starting disk number */ - - unz_file_info cur_file_info; /* public info about the current file in zip*/ - unz_file_info_internal cur_file_info_internal; /* private info about it*/ - file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current - file if we are decompressing it */ - int encrypted; -# ifndef NOUNCRYPT - unsigned long keys[3]; /* keys defining the pseudo-random sequence */ - const unsigned long* pcrc_32_tab; -# endif -} unz_s; - - -#ifndef NOUNCRYPT -#include "crypt.h" -#endif - -/* =========================================================================== - Read a byte from a gz_stream; update next_in and avail_in. Return EOF - for end of file. - IN assertion: the stream s has been sucessfully opened for reading. -*/ - - -local int unzlocal_getByte ( - const zlib_filefunc_def* pzlib_filefunc_def, - voidpf filestream, - int *pi); - -local int unzlocal_getByte(pzlib_filefunc_def,filestream,pi) - const zlib_filefunc_def* pzlib_filefunc_def; - voidpf filestream; - int *pi; -{ - unsigned char c; - int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1); - if (err==1) - { - *pi = (int)c; - return UNZ_OK; - } - else - { - if (ZERROR(*pzlib_filefunc_def,filestream)) - return UNZ_ERRNO; - else - return UNZ_EOF; - } -} - - -/* =========================================================================== - Reads a long in LSB order from the given gz_stream. Sets -*/ -local int unzlocal_getShort ( - const zlib_filefunc_def* pzlib_filefunc_def, - voidpf filestream, - uLong *pX); - -local int unzlocal_getShort (pzlib_filefunc_def,filestream,pX) - const zlib_filefunc_def* pzlib_filefunc_def; - voidpf filestream; - uLong *pX; -{ - uLong x ; - int i; - int err; - - err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); - x = (uLong)i; - - if (err==UNZ_OK) - err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); - x += ((uLong)i)<<8; - - if (err==UNZ_OK) - *pX = x; - else - *pX = 0; - return err; -} - -local int unzlocal_getLong ( - const zlib_filefunc_def* pzlib_filefunc_def, - voidpf filestream, - uLong *pX); - -local int unzlocal_getLong (pzlib_filefunc_def,filestream,pX) - const zlib_filefunc_def* pzlib_filefunc_def; - voidpf filestream; - uLong *pX; -{ - uLong x ; - int i; - int err; - - err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); - x = (uLong)i; - - if (err==UNZ_OK) - err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); - x += ((uLong)i)<<8; - - if (err==UNZ_OK) - err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); - x += ((uLong)i)<<16; - - if (err==UNZ_OK) - err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); - x += ((uLong)i)<<24; - - if (err==UNZ_OK) - *pX = x; - else - *pX = 0; - return err; -} - - -/* My own strcmpi / strcasecmp */ -local int strcmpcasenosensitive_internal (fileName1,fileName2) - const char* fileName1; - const char* fileName2; -{ - for (;;) - { - char c1=*(fileName1++); - char c2=*(fileName2++); - if ((c1>='a') && (c1<='z')) - c1 -= 0x20; - if ((c2>='a') && (c2<='z')) - c2 -= 0x20; - if (c1=='\0') - return ((c2=='\0') ? 0 : -1); - if (c2=='\0') - return 1; - if (c1c2) - return 1; - } -} - - -#ifdef CASESENSITIVITYDEFAULT_NO -#define CASESENSITIVITYDEFAULTVALUE 2 -#else -#define CASESENSITIVITYDEFAULTVALUE 1 -#endif - -#ifndef STRCMPCASENOSENTIVEFUNCTION -#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal -#endif - -/* - Compare two filename (fileName1,fileName2). - If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) - If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi - or strcasecmp) - If iCaseSenisivity = 0, case sensitivity is defaut of your operating system - (like 1 on Unix, 2 on Windows) - -*/ -extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity) - const char* fileName1; - const char* fileName2; - int iCaseSensitivity; -{ - if (iCaseSensitivity==0) - iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; - - if (iCaseSensitivity==1) - return strcmp(fileName1,fileName2); - - return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); -} - -#ifndef BUFREADCOMMENT -#define BUFREADCOMMENT (0x400) -#endif - -/* - Locate the Central directory of a zipfile (at the end, just before - the global comment) -*/ -local uLong unzlocal_SearchCentralDir ( - const zlib_filefunc_def* pzlib_filefunc_def, - voidpf filestream); - -local uLong unzlocal_SearchCentralDir(pzlib_filefunc_def,filestream) - const zlib_filefunc_def* pzlib_filefunc_def; - voidpf filestream; -{ - unsigned char* buf; - uLong uSizeFile; - uLong uBackRead; - uLong uMaxBack=0xffff; /* maximum size of global comment */ - uLong uPosFound=0; - - if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) - return 0; - - - uSizeFile = ZTELL(*pzlib_filefunc_def,filestream); - - if (uMaxBack>uSizeFile) - uMaxBack = uSizeFile; - - buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); - if (buf==NULL) - return 0; - - uBackRead = 4; - while (uBackReaduMaxBack) - uBackRead = uMaxBack; - else - uBackRead+=BUFREADCOMMENT; - uReadPos = uSizeFile-uBackRead ; - - uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? - (BUFREADCOMMENT+4) : (uSizeFile-uReadPos); - if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) - break; - - if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) - break; - - for (i=(int)uReadSize-3; (i--)>0;) - if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && - ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) - { - uPosFound = uReadPos+i; - break; - } - - if (uPosFound!=0) - break; - } - TRYFREE(buf); - return uPosFound; -} - -/* - Open a Zip file. path contain the full pathname (by example, - on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer - "zlib/zlib114.zip". - If the zipfile cannot be opened (file doesn't exist or in not valid), the - return value is NULL. - Else, the return value is a unzFile Handle, usable with other function - of this unzip package. -*/ -extern unzFile ZEXPORT unzOpen2 (path, pzlib_filefunc_def) - const char *path; - zlib_filefunc_def* pzlib_filefunc_def; -{ - unz_s us; - unz_s *s; - uLong central_pos,uL; - - uLong number_disk; /* number of the current dist, used for - spaning ZIP, unsupported, always 0*/ - uLong number_disk_with_CD; /* number the the disk with central dir, used - for spaning ZIP, unsupported, always 0*/ - uLong number_entry_CD; /* total number of entries in - the central dir - (same than number_entry on nospan) */ - - int err=UNZ_OK; - - if (unz_copyright[0]!=' ') - return NULL; - - if (pzlib_filefunc_def==NULL) - fill_fopen_filefunc(&us.z_filefunc); - else - us.z_filefunc = *pzlib_filefunc_def; - - us.filestream= (*(us.z_filefunc.zopen_file))(us.z_filefunc.opaque, - path, - ZLIB_FILEFUNC_MODE_READ | - ZLIB_FILEFUNC_MODE_EXISTING); - if (us.filestream==NULL) - return NULL; - - central_pos = unzlocal_SearchCentralDir(&us.z_filefunc,us.filestream); - if (central_pos==0) - err=UNZ_ERRNO; - - if (ZSEEK(us.z_filefunc, us.filestream, - central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) - err=UNZ_ERRNO; - - /* the signature, already checked */ - if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) - err=UNZ_ERRNO; - - /* number of this disk */ - if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) - err=UNZ_ERRNO; - - /* number of the disk with the start of the central directory */ - if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) - err=UNZ_ERRNO; - - /* total number of entries in the central dir on this disk */ - if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK) - err=UNZ_ERRNO; - - /* total number of entries in the central dir */ - if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK) - err=UNZ_ERRNO; - - if ((number_entry_CD!=us.gi.number_entry) || - (number_disk_with_CD!=0) || - (number_disk!=0)) - err=UNZ_BADZIPFILE; - - /* size of the central directory */ - if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK) - err=UNZ_ERRNO; - - /* offset of start of central directory with respect to the - starting disk number */ - if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK) - err=UNZ_ERRNO; - - /* zipfile comment length */ - if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK) - err=UNZ_ERRNO; - - if ((central_pospfile_in_zip_read!=NULL) - unzCloseCurrentFile(file); - - ZCLOSE(s->z_filefunc, s->filestream); - TRYFREE(s); - return UNZ_OK; -} - - -/* - Write info about the ZipFile in the *pglobal_info structure. - No preparation of the structure is needed - return UNZ_OK if there is no problem. */ -extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info) - unzFile file; - unz_global_info *pglobal_info; -{ - unz_s* s; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - *pglobal_info=s->gi; - return UNZ_OK; -} - - -/* - Translate date/time from Dos format to tm_unz (readable more easilty) -*/ -local void unzlocal_DosDateToTmuDate (ulDosDate, ptm) - uLong ulDosDate; - tm_unz* ptm; -{ - uLong uDate; - uDate = (uLong)(ulDosDate>>16); - ptm->tm_mday = (uInt)(uDate&0x1f) ; - ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; - ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; - - ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); - ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; - ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; -} - -/* - Get Info about the current file in the zipfile, with internal only info -*/ -local int unzlocal_GetCurrentFileInfoInternal (unzFile file, - unz_file_info *pfile_info, - unz_file_info_internal - *pfile_info_internal, - char *szFileName, - uLong fileNameBufferSize, - void *extraField, - uLong extraFieldBufferSize, - char *szComment, - uLong commentBufferSize); - -local int unzlocal_GetCurrentFileInfoInternal (file, - pfile_info, - pfile_info_internal, - szFileName, fileNameBufferSize, - extraField, extraFieldBufferSize, - szComment, commentBufferSize) - unzFile file; - unz_file_info *pfile_info; - unz_file_info_internal *pfile_info_internal; - char *szFileName; - uLong fileNameBufferSize; - void *extraField; - uLong extraFieldBufferSize; - char *szComment; - uLong commentBufferSize; -{ - unz_s* s; - unz_file_info file_info; - unz_file_info_internal file_info_internal; - int err=UNZ_OK; - uLong uMagic; - long lSeek=0; - - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - if (ZSEEK(s->z_filefunc, s->filestream, - s->pos_in_central_dir+s->byte_before_the_zipfile, - ZLIB_FILEFUNC_SEEK_SET)!=0) - err=UNZ_ERRNO; - - - /* we check the magic */ - if (err==UNZ_OK) - { - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) - err=UNZ_ERRNO; - else if (uMagic!=0x02014b50) - err=UNZ_BADZIPFILE; - } - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK) - err=UNZ_ERRNO; - - unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); - - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK) - err=UNZ_ERRNO; - - lSeek+=file_info.size_filename; - if ((err==UNZ_OK) && (szFileName!=NULL)) - { - uLong uSizeRead ; - if (file_info.size_filename0) && (fileNameBufferSize>0)) - if (ZREAD(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead) - err=UNZ_ERRNO; - lSeek -= uSizeRead; - } - - - if ((err==UNZ_OK) && (extraField!=NULL)) - { - uLong uSizeRead ; - if (file_info.size_file_extraz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) - lSeek=0; - else - err=UNZ_ERRNO; - } - if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) - if (ZREAD(s->z_filefunc, s->filestream,extraField,uSizeRead)!=uSizeRead) - err=UNZ_ERRNO; - lSeek += file_info.size_file_extra - uSizeRead; - } - else - lSeek+=file_info.size_file_extra; - - - if ((err==UNZ_OK) && (szComment!=NULL)) - { - uLong uSizeRead ; - if (file_info.size_file_commentz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) - lSeek=0; - else - err=UNZ_ERRNO; - } - if ((file_info.size_file_comment>0) && (commentBufferSize>0)) - if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead) - err=UNZ_ERRNO; - lSeek+=file_info.size_file_comment - uSizeRead; - } - else - lSeek+=file_info.size_file_comment; - - if ((err==UNZ_OK) && (pfile_info!=NULL)) - *pfile_info=file_info; - - if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) - *pfile_info_internal=file_info_internal; - - return err; -} - - - -/* - Write info about the ZipFile in the *pglobal_info structure. - No preparation of the structure is needed - return UNZ_OK if there is no problem. -*/ -extern int ZEXPORT unzGetCurrentFileInfo (file, - pfile_info, - szFileName, fileNameBufferSize, - extraField, extraFieldBufferSize, - szComment, commentBufferSize) - unzFile file; - unz_file_info *pfile_info; - char *szFileName; - uLong fileNameBufferSize; - void *extraField; - uLong extraFieldBufferSize; - char *szComment; - uLong commentBufferSize; -{ - return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL, - szFileName,fileNameBufferSize, - extraField,extraFieldBufferSize, - szComment,commentBufferSize); -} - -/* - Set the current file of the zipfile to the first file. - return UNZ_OK if there is no problem -*/ -extern int ZEXPORT unzGoToFirstFile (file) - unzFile file; -{ - int err=UNZ_OK; - unz_s* s; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - s->pos_in_central_dir=s->offset_central_dir; - s->num_file=0; - err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, - &s->cur_file_info_internal, - NULL,0,NULL,0,NULL,0); - s->current_file_ok = (err == UNZ_OK); - return err; -} - -/* - Set the current file of the zipfile to the next file. - return UNZ_OK if there is no problem - return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. -*/ -extern int ZEXPORT unzGoToNextFile (file) - unzFile file; -{ - unz_s* s; - int err; - - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - if (!s->current_file_ok) - return UNZ_END_OF_LIST_OF_FILE; - if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */ - if (s->num_file+1==s->gi.number_entry) - return UNZ_END_OF_LIST_OF_FILE; - - s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + - s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; - s->num_file++; - err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, - &s->cur_file_info_internal, - NULL,0,NULL,0,NULL,0); - s->current_file_ok = (err == UNZ_OK); - return err; -} - - -/* - Try locate the file szFileName in the zipfile. - For the iCaseSensitivity signification, see unzipStringFileNameCompare - - return value : - UNZ_OK if the file is found. It becomes the current file. - UNZ_END_OF_LIST_OF_FILE if the file is not found -*/ -extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity) - unzFile file; - const char *szFileName; - int iCaseSensitivity; -{ - unz_s* s; - int err; - - /* We remember the 'current' position in the file so that we can jump - * back there if we fail. - */ - unz_file_info cur_file_infoSaved; - unz_file_info_internal cur_file_info_internalSaved; - uLong num_fileSaved; - uLong pos_in_central_dirSaved; - - - if (file==NULL) - return UNZ_PARAMERROR; - - if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) - return UNZ_PARAMERROR; - - s=(unz_s*)file; - if (!s->current_file_ok) - return UNZ_END_OF_LIST_OF_FILE; - - /* Save the current state */ - num_fileSaved = s->num_file; - pos_in_central_dirSaved = s->pos_in_central_dir; - cur_file_infoSaved = s->cur_file_info; - cur_file_info_internalSaved = s->cur_file_info_internal; - - err = unzGoToFirstFile(file); - - while (err == UNZ_OK) - { - char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; - err = unzGetCurrentFileInfo(file,NULL, - szCurrentFileName,sizeof(szCurrentFileName)-1, - NULL,0,NULL,0); - if (err == UNZ_OK) - { - if (unzStringFileNameCompare(szCurrentFileName, - szFileName,iCaseSensitivity)==0) - return UNZ_OK; - err = unzGoToNextFile(file); - } - } - - /* We failed, so restore the state of the 'current file' to where we - * were. - */ - s->num_file = num_fileSaved ; - s->pos_in_central_dir = pos_in_central_dirSaved ; - s->cur_file_info = cur_file_infoSaved; - s->cur_file_info_internal = cur_file_info_internalSaved; - return err; -} - - -/* -/////////////////////////////////////////// -// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net) -// I need random access -// -// Further optimization could be realized by adding an ability -// to cache the directory in memory. The goal being a single -// comprehensive file read to put the file I need in a memory. -*/ - -/* -typedef struct unz_file_pos_s -{ - uLong pos_in_zip_directory; // offset in file - uLong num_of_file; // # of file -} unz_file_pos; -*/ - -extern int ZEXPORT unzGetFilePos(file, file_pos) - unzFile file; - unz_file_pos* file_pos; -{ - unz_s* s; - - if (file==NULL || file_pos==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - if (!s->current_file_ok) - return UNZ_END_OF_LIST_OF_FILE; - - file_pos->pos_in_zip_directory = s->pos_in_central_dir; - file_pos->num_of_file = s->num_file; - - return UNZ_OK; -} - -extern int ZEXPORT unzGoToFilePos(file, file_pos) - unzFile file; - unz_file_pos* file_pos; -{ - unz_s* s; - int err; - - if (file==NULL || file_pos==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - - /* jump to the right spot */ - s->pos_in_central_dir = file_pos->pos_in_zip_directory; - s->num_file = file_pos->num_of_file; - - /* set the current file */ - err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, - &s->cur_file_info_internal, - NULL,0,NULL,0,NULL,0); - /* return results */ - s->current_file_ok = (err == UNZ_OK); - return err; -} - -/* -// Unzip Helper Functions - should be here? -/////////////////////////////////////////// -*/ - -/* - Read the local header of the current zipfile - Check the coherency of the local header and info in the end of central - directory about this file - store in *piSizeVar the size of extra info in local header - (filename and size of extra field data) -*/ -local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar, - poffset_local_extrafield, - psize_local_extrafield) - unz_s* s; - uInt* piSizeVar; - uLong *poffset_local_extrafield; - uInt *psize_local_extrafield; -{ - uLong uMagic,uData,uFlags; - uLong size_filename; - uLong size_extra_field; - int err=UNZ_OK; - - *piSizeVar = 0; - *poffset_local_extrafield = 0; - *psize_local_extrafield = 0; - - if (ZSEEK(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile + - s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0) - return UNZ_ERRNO; - - - if (err==UNZ_OK) - { - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) - err=UNZ_ERRNO; - else if (uMagic!=0x04034b50) - err=UNZ_BADZIPFILE; - } - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) - err=UNZ_ERRNO; -/* - else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) - err=UNZ_BADZIPFILE; -*/ - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) - err=UNZ_ERRNO; - else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) - err=UNZ_BADZIPFILE; - - if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && - (s->cur_file_info.compression_method!=Z_DEFLATED)) - err=UNZ_BADZIPFILE; - - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */ - err=UNZ_ERRNO; - - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */ - err=UNZ_ERRNO; - else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && - ((uFlags & 8)==0)) - err=UNZ_BADZIPFILE; - - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */ - err=UNZ_ERRNO; - else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && - ((uFlags & 8)==0)) - err=UNZ_BADZIPFILE; - - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */ - err=UNZ_ERRNO; - else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && - ((uFlags & 8)==0)) - err=UNZ_BADZIPFILE; - - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK) - err=UNZ_ERRNO; - else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) - err=UNZ_BADZIPFILE; - - *piSizeVar += (uInt)size_filename; - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK) - err=UNZ_ERRNO; - *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + - SIZEZIPLOCALHEADER + size_filename; - *psize_local_extrafield = (uInt)size_extra_field; - - *piSizeVar += (uInt)size_extra_field; - - return err; -} - -/* - Open for reading data the current file in the zipfile. - If there is no error and the file is opened, the return value is UNZ_OK. -*/ -extern int ZEXPORT unzOpenCurrentFile3 (file, method, level, raw, password) - unzFile file; - int* method; - int* level; - int raw; - const char* password; -{ - int err=UNZ_OK; - uInt iSizeVar; - unz_s* s; - file_in_zip_read_info_s* pfile_in_zip_read_info; - uLong offset_local_extrafield; /* offset of the local extra field */ - uInt size_local_extrafield; /* size of the local extra field */ -# ifndef NOUNCRYPT - char source[12]; -# else - if (password != NULL) - return UNZ_PARAMERROR; -# endif - - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - if (!s->current_file_ok) - return UNZ_PARAMERROR; - - if (s->pfile_in_zip_read != NULL) - unzCloseCurrentFile(file); - - if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar, - &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) - return UNZ_BADZIPFILE; - - pfile_in_zip_read_info = (file_in_zip_read_info_s*) - ALLOC(sizeof(file_in_zip_read_info_s)); - if (pfile_in_zip_read_info==NULL) - return UNZ_INTERNALERROR; - - pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); - pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; - pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; - pfile_in_zip_read_info->pos_local_extrafield=0; - pfile_in_zip_read_info->raw=raw; - - if (pfile_in_zip_read_info->read_buffer==NULL) - { - TRYFREE(pfile_in_zip_read_info); - return UNZ_INTERNALERROR; - } - - pfile_in_zip_read_info->stream_initialised=0; - - if (method!=NULL) - *method = (int)s->cur_file_info.compression_method; - - if (level!=NULL) - { - *level = 6; - switch (s->cur_file_info.flag & 0x06) - { - case 6 : *level = 1; break; - case 4 : *level = 2; break; - case 2 : *level = 9; break; - } - } - - if ((s->cur_file_info.compression_method!=0) && - (s->cur_file_info.compression_method!=Z_DEFLATED)) - err=UNZ_BADZIPFILE; - - pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; - pfile_in_zip_read_info->crc32=0; - pfile_in_zip_read_info->compression_method = - s->cur_file_info.compression_method; - pfile_in_zip_read_info->filestream=s->filestream; - pfile_in_zip_read_info->z_filefunc=s->z_filefunc; - pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; - - pfile_in_zip_read_info->stream.total_out = 0; - - if ((s->cur_file_info.compression_method==Z_DEFLATED) && - (!raw)) - { - pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; - pfile_in_zip_read_info->stream.zfree = (free_func)0; - pfile_in_zip_read_info->stream.opaque = (voidpf)0; - pfile_in_zip_read_info->stream.next_in = (voidpf)0; - pfile_in_zip_read_info->stream.avail_in = 0; - - err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); - if (err == Z_OK) - pfile_in_zip_read_info->stream_initialised=1; - else - { - TRYFREE(pfile_in_zip_read_info); - return err; - } - /* windowBits is passed < 0 to tell that there is no zlib header. - * Note that in this case inflate *requires* an extra "dummy" byte - * after the compressed stream in order to complete decompression and - * return Z_STREAM_END. - * In unzip, i don't wait absolutely Z_STREAM_END because I known the - * size of both compressed and uncompressed data - */ - } - pfile_in_zip_read_info->rest_read_compressed = - s->cur_file_info.compressed_size ; - pfile_in_zip_read_info->rest_read_uncompressed = - s->cur_file_info.uncompressed_size ; - - - pfile_in_zip_read_info->pos_in_zipfile = - s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + - iSizeVar; - - pfile_in_zip_read_info->stream.avail_in = (uInt)0; - - s->pfile_in_zip_read = pfile_in_zip_read_info; - -# ifndef NOUNCRYPT - if (password != NULL) - { - int i; - s->pcrc_32_tab = get_crc_table(); - init_keys(password,s->keys,s->pcrc_32_tab); - if (ZSEEK(s->z_filefunc, s->filestream, - s->pfile_in_zip_read->pos_in_zipfile + - s->pfile_in_zip_read->byte_before_the_zipfile, - SEEK_SET)!=0) - return UNZ_INTERNALERROR; - if(ZREAD(s->z_filefunc, s->filestream,source, 12)<12) - return UNZ_INTERNALERROR; - - for (i = 0; i<12; i++) - zdecode(s->keys,s->pcrc_32_tab,source[i]); - - s->pfile_in_zip_read->pos_in_zipfile+=12; - s->encrypted=1; - } -# endif - - - return UNZ_OK; -} - -extern int ZEXPORT unzOpenCurrentFile (file) - unzFile file; -{ - return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); -} - -extern int ZEXPORT unzOpenCurrentFilePassword (file, password) - unzFile file; - const char* password; -{ - return unzOpenCurrentFile3(file, NULL, NULL, 0, password); -} - -extern int ZEXPORT unzOpenCurrentFile2 (file,method,level,raw) - unzFile file; - int* method; - int* level; - int raw; -{ - return unzOpenCurrentFile3(file, method, level, raw, NULL); -} - -/* - Read bytes from the current file. - buf contain buffer where data must be copied - len the size of buf. - - return the number of byte copied if somes bytes are copied - return 0 if the end of file was reached - return <0 with error code if there is an error - (UNZ_ERRNO for IO error, or zLib error for uncompress error) -*/ -extern int ZEXPORT unzReadCurrentFile (file, buf, len) - unzFile file; - voidp buf; - unsigned len; -{ - int err=UNZ_OK; - uInt iRead = 0; - unz_s* s; - file_in_zip_read_info_s* pfile_in_zip_read_info; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; - - if (pfile_in_zip_read_info==NULL) - return UNZ_PARAMERROR; - - - if (pfile_in_zip_read_info->read_buffer == NULL) - return UNZ_END_OF_LIST_OF_FILE; - if (len==0) - return 0; - - pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; - - pfile_in_zip_read_info->stream.avail_out = (uInt)len; - - if ((len>pfile_in_zip_read_info->rest_read_uncompressed) && - (!(pfile_in_zip_read_info->raw))) - pfile_in_zip_read_info->stream.avail_out = - (uInt)pfile_in_zip_read_info->rest_read_uncompressed; - - if ((len>pfile_in_zip_read_info->rest_read_compressed+ - pfile_in_zip_read_info->stream.avail_in) && - (pfile_in_zip_read_info->raw)) - pfile_in_zip_read_info->stream.avail_out = - (uInt)pfile_in_zip_read_info->rest_read_compressed+ - pfile_in_zip_read_info->stream.avail_in; - - while (pfile_in_zip_read_info->stream.avail_out>0) - { - if ((pfile_in_zip_read_info->stream.avail_in==0) && - (pfile_in_zip_read_info->rest_read_compressed>0)) - { - uInt uReadThis = UNZ_BUFSIZE; - if (pfile_in_zip_read_info->rest_read_compressedrest_read_compressed; - if (uReadThis == 0) - return UNZ_EOF; - if (ZSEEK(pfile_in_zip_read_info->z_filefunc, - pfile_in_zip_read_info->filestream, - pfile_in_zip_read_info->pos_in_zipfile + - pfile_in_zip_read_info->byte_before_the_zipfile, - ZLIB_FILEFUNC_SEEK_SET)!=0) - return UNZ_ERRNO; - if (ZREAD(pfile_in_zip_read_info->z_filefunc, - pfile_in_zip_read_info->filestream, - pfile_in_zip_read_info->read_buffer, - uReadThis)!=uReadThis) - return UNZ_ERRNO; - - -# ifndef NOUNCRYPT - if(s->encrypted) - { - uInt i; - for(i=0;iread_buffer[i] = - zdecode(s->keys,s->pcrc_32_tab, - pfile_in_zip_read_info->read_buffer[i]); - } -# endif - - - pfile_in_zip_read_info->pos_in_zipfile += uReadThis; - - pfile_in_zip_read_info->rest_read_compressed-=uReadThis; - - pfile_in_zip_read_info->stream.next_in = - (Bytef*)pfile_in_zip_read_info->read_buffer; - pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; - } - - if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw)) - { - uInt uDoCopy,i ; - - if ((pfile_in_zip_read_info->stream.avail_in == 0) && - (pfile_in_zip_read_info->rest_read_compressed == 0)) - return (iRead==0) ? UNZ_EOF : iRead; - - if (pfile_in_zip_read_info->stream.avail_out < - pfile_in_zip_read_info->stream.avail_in) - uDoCopy = pfile_in_zip_read_info->stream.avail_out ; - else - uDoCopy = pfile_in_zip_read_info->stream.avail_in ; - - for (i=0;istream.next_out+i) = - *(pfile_in_zip_read_info->stream.next_in+i); - - pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, - pfile_in_zip_read_info->stream.next_out, - uDoCopy); - pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; - pfile_in_zip_read_info->stream.avail_in -= uDoCopy; - pfile_in_zip_read_info->stream.avail_out -= uDoCopy; - pfile_in_zip_read_info->stream.next_out += uDoCopy; - pfile_in_zip_read_info->stream.next_in += uDoCopy; - pfile_in_zip_read_info->stream.total_out += uDoCopy; - iRead += uDoCopy; - } - else - { - uLong uTotalOutBefore,uTotalOutAfter; - const Bytef *bufBefore; - uLong uOutThis; - int flush=Z_SYNC_FLUSH; - - uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; - bufBefore = pfile_in_zip_read_info->stream.next_out; - - /* - if ((pfile_in_zip_read_info->rest_read_uncompressed == - pfile_in_zip_read_info->stream.avail_out) && - (pfile_in_zip_read_info->rest_read_compressed == 0)) - flush = Z_FINISH; - */ - err=inflate(&pfile_in_zip_read_info->stream,flush); - - if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL)) - err = Z_DATA_ERROR; - - uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; - uOutThis = uTotalOutAfter-uTotalOutBefore; - - pfile_in_zip_read_info->crc32 = - crc32(pfile_in_zip_read_info->crc32,bufBefore, - (uInt)(uOutThis)); - - pfile_in_zip_read_info->rest_read_uncompressed -= - uOutThis; - - iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); - - if (err==Z_STREAM_END) - return (iRead==0) ? UNZ_EOF : iRead; - if (err!=Z_OK) - break; - } - } - - if (err==Z_OK) - return iRead; - return err; -} - - -/* - Give the current position in uncompressed data -*/ -extern z_off_t ZEXPORT unztell (file) - unzFile file; -{ - unz_s* s; - file_in_zip_read_info_s* pfile_in_zip_read_info; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; - - if (pfile_in_zip_read_info==NULL) - return UNZ_PARAMERROR; - - return (z_off_t)pfile_in_zip_read_info->stream.total_out; -} - - -/* - return 1 if the end of file was reached, 0 elsewhere -*/ -extern int ZEXPORT unzeof (file) - unzFile file; -{ - unz_s* s; - file_in_zip_read_info_s* pfile_in_zip_read_info; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; - - if (pfile_in_zip_read_info==NULL) - return UNZ_PARAMERROR; - - if (pfile_in_zip_read_info->rest_read_uncompressed == 0) - return 1; - else - return 0; -} - - - -/* - Read extra field from the current file (opened by unzOpenCurrentFile) - This is the local-header version of the extra field (sometimes, there is - more info in the local-header version than in the central-header) - - if buf==NULL, it return the size of the local extra field that can be read - - if buf!=NULL, len is the size of the buffer, the extra header is copied in - buf. - the return value is the number of bytes copied in buf, or (if <0) - the error code -*/ -extern int ZEXPORT unzGetLocalExtrafield (file,buf,len) - unzFile file; - voidp buf; - unsigned len; -{ - unz_s* s; - file_in_zip_read_info_s* pfile_in_zip_read_info; - uInt read_now; - uLong size_to_read; - - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; - - if (pfile_in_zip_read_info==NULL) - return UNZ_PARAMERROR; - - size_to_read = (pfile_in_zip_read_info->size_local_extrafield - - pfile_in_zip_read_info->pos_local_extrafield); - - if (buf==NULL) - return (int)size_to_read; - - if (len>size_to_read) - read_now = (uInt)size_to_read; - else - read_now = (uInt)len ; - - if (read_now==0) - return 0; - - if (ZSEEK(pfile_in_zip_read_info->z_filefunc, - pfile_in_zip_read_info->filestream, - pfile_in_zip_read_info->offset_local_extrafield + - pfile_in_zip_read_info->pos_local_extrafield, - ZLIB_FILEFUNC_SEEK_SET)!=0) - return UNZ_ERRNO; - - if (ZREAD(pfile_in_zip_read_info->z_filefunc, - pfile_in_zip_read_info->filestream, - buf,read_now)!=read_now) - return UNZ_ERRNO; - - return (int)read_now; -} - -/* - Close the file in zip opened with unzipOpenCurrentFile - Return UNZ_CRCERROR if all the file was read but the CRC is not good -*/ -extern int ZEXPORT unzCloseCurrentFile (file) - unzFile file; -{ - int err=UNZ_OK; - - unz_s* s; - file_in_zip_read_info_s* pfile_in_zip_read_info; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; - - if (pfile_in_zip_read_info==NULL) - return UNZ_PARAMERROR; - - - if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && - (!pfile_in_zip_read_info->raw)) - { - if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) - err=UNZ_CRCERROR; - } - - - TRYFREE(pfile_in_zip_read_info->read_buffer); - pfile_in_zip_read_info->read_buffer = NULL; - if (pfile_in_zip_read_info->stream_initialised) - inflateEnd(&pfile_in_zip_read_info->stream); - - pfile_in_zip_read_info->stream_initialised = 0; - TRYFREE(pfile_in_zip_read_info); - - s->pfile_in_zip_read=NULL; - - return err; -} - - -/* - Get the global comment string of the ZipFile, in the szComment buffer. - uSizeBuf is the size of the szComment buffer. - return the number of byte copied or an error code <0 -*/ -extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf) - unzFile file; - char *szComment; - uLong uSizeBuf; -{ - unz_s* s; - uLong uReadThis ; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - - uReadThis = uSizeBuf; - if (uReadThis>s->gi.size_comment) - uReadThis = s->gi.size_comment; - - if (ZSEEK(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0) - return UNZ_ERRNO; - - if (uReadThis>0) - { - *szComment='\0'; - if (ZREAD(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis) - return UNZ_ERRNO; - } - - if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) - *(szComment+s->gi.size_comment)='\0'; - return (int)uReadThis; -} - -/* Additions by RX '2004 */ -extern uLong ZEXPORT unzGetOffset (file) - unzFile file; -{ - unz_s* s; - - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - if (!s->current_file_ok) - return 0; - if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff) - if (s->num_file==s->gi.number_entry) - return 0; - return s->pos_in_central_dir; -} - -extern int ZEXPORT unzSetOffset (file, pos) - unzFile file; - uLong pos; -{ - unz_s* s; - int err; - - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - - s->pos_in_central_dir = pos; - s->num_file = s->gi.number_entry; /* hack */ - err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, - &s->cur_file_info_internal, - NULL,0,NULL,0,NULL,0); - s->current_file_ok = (err == UNZ_OK); - return err; -} +/* unzip.c -- IO for uncompress .zip files using zlib + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant + + Read unzip.h for more info +*/ + +/* Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of +compatibility with older software. The following is from the original crypt.c. Code +woven in by Terry Thorsen 1/2003. +*/ +/* + Copyright (c) 1990-2000 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* + crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h] + + The encryption/decryption parts of this source code (as opposed to the + non-echoing password parts) were originally written in Europe. The + whole source package can be freely distributed, including from the USA. + (Prior to January 2000, re-export from the US was a violation of US law.) + */ + +/* + This encryption code is a direct transcription of the algorithm from + Roger Schlafly, described by Phil Katz in the file appnote.txt. This + file (appnote.txt) is distributed with the PKZIP program (even in the + version without encryption capabilities). + */ + + +#include +#include +#include +#include "./unzip.h" + +#ifdef STDC +# include +# include +# include +#endif +#ifdef NO_ERRNO_H + extern int errno; +#else +# include +#endif + + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + + +#ifndef CASESENSITIVITYDEFAULT_NO +# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) +# define CASESENSITIVITYDEFAULT_NO +# endif +#endif + + +#ifndef UNZ_BUFSIZE +#define UNZ_BUFSIZE (16384) +#endif + +#ifndef UNZ_MAXFILENAMEINZIP +#define UNZ_MAXFILENAMEINZIP (256) +#endif + +#ifndef ALLOC +# define ALLOC(size) (malloc(size)) +#endif +#ifndef TRYFREE +# define TRYFREE(p) {if (p) free(p);} +#endif + +#define SIZECENTRALDIRITEM (0x2e) +#define SIZEZIPLOCALHEADER (0x1e) + + + + +const char unz_copyright[] = + " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; + +/* unz_file_info_interntal contain internal info about a file in zipfile*/ +typedef struct unz_file_info_internal_s +{ + uLong offset_curfile;/* relative offset of local header 4 bytes */ +} unz_file_info_internal; + + +/* file_in_zip_read_info_s contain internal information about a file in zipfile, + when reading and decompress it */ +typedef struct +{ + char *read_buffer; /* internal buffer for compressed data */ + z_stream stream; /* zLib stream structure for inflate */ + + uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ + uLong stream_initialised; /* flag set if stream structure is initialised*/ + + uLong offset_local_extrafield;/* offset of the local extra field */ + uInt size_local_extrafield;/* size of the local extra field */ + uLong pos_local_extrafield; /* position in the local extra field in read*/ + + uLong crc32; /* crc32 of all data uncompressed */ + uLong crc32_wait; /* crc32 we must obtain after decompress all */ + uLong rest_read_compressed; /* number of byte to be decompressed */ + uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/ + zlib_filefunc_def z_filefunc; + voidpf filestream; /* io structore of the zipfile */ + uLong compression_method; /* compression method (0==store) */ + uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + int raw; +} file_in_zip_read_info_s; + + +/* unz_s contain internal information about the zipfile +*/ +typedef struct +{ + zlib_filefunc_def z_filefunc; + voidpf filestream; /* io structore of the zipfile */ + unz_global_info gi; /* public global information */ + uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + uLong num_file; /* number of the current file in the zipfile*/ + uLong pos_in_central_dir; /* pos of the current file in the central dir*/ + uLong current_file_ok; /* flag about the usability of the current file*/ + uLong central_pos; /* position of the beginning of the central dir*/ + + uLong size_central_dir; /* size of the central directory */ + uLong offset_central_dir; /* offset of start of central directory with + respect to the starting disk number */ + + unz_file_info cur_file_info; /* public info about the current file in zip*/ + unz_file_info_internal cur_file_info_internal; /* private info about it*/ + file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current + file if we are decompressing it */ + int encrypted; +# ifndef NOUNCRYPT + unsigned long keys[3]; /* keys defining the pseudo-random sequence */ + const unsigned long* pcrc_32_tab; +# endif +} unz_s; + + +#ifndef NOUNCRYPT +#include "crypt.h" +#endif + +/* =========================================================================== + Read a byte from a gz_stream; update next_in and avail_in. Return EOF + for end of file. + IN assertion: the stream s has been sucessfully opened for reading. +*/ + + +local int unzlocal_getByte ( + const zlib_filefunc_def* pzlib_filefunc_def, + voidpf filestream, + int *pi); + +local int unzlocal_getByte(pzlib_filefunc_def,filestream,pi) + const zlib_filefunc_def* pzlib_filefunc_def; + voidpf filestream; + int *pi; +{ + unsigned char c; + int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1); + if (err==1) + { + *pi = (int)c; + return UNZ_OK; + } + else + { + if (ZERROR(*pzlib_filefunc_def,filestream)) + return UNZ_ERRNO; + else + return UNZ_EOF; + } +} + + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets +*/ +local int unzlocal_getShort ( + const zlib_filefunc_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX); + +local int unzlocal_getShort (pzlib_filefunc_def,filestream,pX) + const zlib_filefunc_def* pzlib_filefunc_def; + voidpf filestream; + uLong *pX; +{ + uLong x ; + int i; + int err; + + err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<8; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int unzlocal_getLong ( + const zlib_filefunc_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX); + +local int unzlocal_getLong (pzlib_filefunc_def,filestream,pX) + const zlib_filefunc_def* pzlib_filefunc_def; + voidpf filestream; + uLong *pX; +{ + uLong x ; + int i; + int err; + + err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<8; + + if (err==UNZ_OK) + err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<16; + + if (err==UNZ_OK) + err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<24; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + + +/* My own strcmpi / strcasecmp */ +local int strcmpcasenosensitive_internal (fileName1,fileName2) + const char* fileName1; + const char* fileName2; +{ + for (;;) + { + char c1=*(fileName1++); + char c2=*(fileName2++); + if ((c1>='a') && (c1<='z')) + c1 -= 0x20; + if ((c2>='a') && (c2<='z')) + c2 -= 0x20; + if (c1=='\0') + return ((c2=='\0') ? 0 : -1); + if (c2=='\0') + return 1; + if (c1c2) + return 1; + } +} + + +#ifdef CASESENSITIVITYDEFAULT_NO +#define CASESENSITIVITYDEFAULTVALUE 2 +#else +#define CASESENSITIVITYDEFAULTVALUE 1 +#endif + +#ifndef STRCMPCASENOSENTIVEFUNCTION +#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal +#endif + +/* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) + +*/ +extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity) + const char* fileName1; + const char* fileName2; + int iCaseSensitivity; +{ + if (iCaseSensitivity==0) + iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; + + if (iCaseSensitivity==1) + return strcmp(fileName1,fileName2); + + return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); +} + +#ifndef BUFREADCOMMENT +#define BUFREADCOMMENT (0x400) +#endif + +/* + Locate the Central directory of a zipfile (at the end, just before + the global comment) +*/ +local uLong unzlocal_SearchCentralDir ( + const zlib_filefunc_def* pzlib_filefunc_def, + voidpf filestream); + +local uLong unzlocal_SearchCentralDir(pzlib_filefunc_def,filestream) + const zlib_filefunc_def* pzlib_filefunc_def; + voidpf filestream; +{ + unsigned char* buf; + uLong uSizeFile; + uLong uBackRead; + uLong uMaxBack=0xffff; /* maximum size of global comment */ + uLong uPosFound=0; + + if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + + + uSizeFile = ZTELL(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uSizeFile-uReadPos); + if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && + ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) + { + uPosFound = uReadPos+i; + break; + } + + if (uPosFound!=0) + break; + } + TRYFREE(buf); + return uPosFound; +} + +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer + "zlib/zlib114.zip". + If the zipfile cannot be opened (file doesn't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. +*/ +extern unzFile ZEXPORT unzOpen2 (path, pzlib_filefunc_def) + const char *path; + zlib_filefunc_def* pzlib_filefunc_def; +{ + unz_s us; + unz_s *s; + uLong central_pos,uL; + + uLong number_disk; /* number of the current dist, used for + spaning ZIP, unsupported, always 0*/ + uLong number_disk_with_CD; /* number the the disk with central dir, used + for spaning ZIP, unsupported, always 0*/ + uLong number_entry_CD; /* total number of entries in + the central dir + (same than number_entry on nospan) */ + + int err=UNZ_OK; + + if (unz_copyright[0]!=' ') + return NULL; + + if (pzlib_filefunc_def==NULL) + fill_fopen_filefunc(&us.z_filefunc); + else + us.z_filefunc = *pzlib_filefunc_def; + + us.filestream= (*(us.z_filefunc.zopen_file))(us.z_filefunc.opaque, + path, + ZLIB_FILEFUNC_MODE_READ | + ZLIB_FILEFUNC_MODE_EXISTING); + if (us.filestream==NULL) + return NULL; + + central_pos = unzlocal_SearchCentralDir(&us.z_filefunc,us.filestream); + if (central_pos==0) + err=UNZ_ERRNO; + + if (ZSEEK(us.z_filefunc, us.filestream, + central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) + err=UNZ_ERRNO; + + /* the signature, already checked */ + if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of this disk */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of the disk with the start of the central directory */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central dir on this disk */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central dir */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + if ((number_entry_CD!=us.gi.number_entry) || + (number_disk_with_CD!=0) || + (number_disk!=0)) + err=UNZ_BADZIPFILE; + + /* size of the central directory */ + if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + /* offset of start of central directory with respect to the + starting disk number */ + if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + /* zipfile comment length */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK) + err=UNZ_ERRNO; + + if ((central_pospfile_in_zip_read!=NULL) + unzCloseCurrentFile(file); + + ZCLOSE(s->z_filefunc, s->filestream); + TRYFREE(s); + return UNZ_OK; +} + + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ +extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info) + unzFile file; + unz_global_info *pglobal_info; +{ + unz_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + *pglobal_info=s->gi; + return UNZ_OK; +} + + +/* + Translate date/time from Dos format to tm_unz (readable more easilty) +*/ +local void unzlocal_DosDateToTmuDate (ulDosDate, ptm) + uLong ulDosDate; + tm_unz* ptm; +{ + uLong uDate; + uDate = (uLong)(ulDosDate>>16); + ptm->tm_mday = (uInt)(uDate&0x1f) ; + ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; + ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; + + ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); + ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; + ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; +} + +/* + Get Info about the current file in the zipfile, with internal only info +*/ +local int unzlocal_GetCurrentFileInfoInternal (unzFile file, + unz_file_info *pfile_info, + unz_file_info_internal + *pfile_info_internal, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize); + +local int unzlocal_GetCurrentFileInfoInternal (file, + pfile_info, + pfile_info_internal, + szFileName, fileNameBufferSize, + extraField, extraFieldBufferSize, + szComment, commentBufferSize) + unzFile file; + unz_file_info *pfile_info; + unz_file_info_internal *pfile_info_internal; + char *szFileName; + uLong fileNameBufferSize; + void *extraField; + uLong extraFieldBufferSize; + char *szComment; + uLong commentBufferSize; +{ + unz_s* s; + unz_file_info file_info; + unz_file_info_internal file_info_internal; + int err=UNZ_OK; + uLong uMagic; + long lSeek=0; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (ZSEEK(s->z_filefunc, s->filestream, + s->pos_in_central_dir+s->byte_before_the_zipfile, + ZLIB_FILEFUNC_SEEK_SET)!=0) + err=UNZ_ERRNO; + + + /* we check the magic */ + if (err==UNZ_OK) + { + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x02014b50) + err=UNZ_BADZIPFILE; + } + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK) + err=UNZ_ERRNO; + + unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK) + err=UNZ_ERRNO; + + lSeek+=file_info.size_filename; + if ((err==UNZ_OK) && (szFileName!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_filename0) && (fileNameBufferSize>0)) + if (ZREAD(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + lSeek -= uSizeRead; + } + + + if ((err==UNZ_OK) && (extraField!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_file_extraz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + } + if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) + if (ZREAD(s->z_filefunc, s->filestream,extraField,uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + lSeek += file_info.size_file_extra - uSizeRead; + } + else + lSeek+=file_info.size_file_extra; + + + if ((err==UNZ_OK) && (szComment!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_file_commentz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + } + if ((file_info.size_file_comment>0) && (commentBufferSize>0)) + if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + lSeek+=file_info.size_file_comment - uSizeRead; + } + else + lSeek+=file_info.size_file_comment; + + if ((err==UNZ_OK) && (pfile_info!=NULL)) + *pfile_info=file_info; + + if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) + *pfile_info_internal=file_info_internal; + + return err; +} + + + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. +*/ +extern int ZEXPORT unzGetCurrentFileInfo (file, + pfile_info, + szFileName, fileNameBufferSize, + extraField, extraFieldBufferSize, + szComment, commentBufferSize) + unzFile file; + unz_file_info *pfile_info; + char *szFileName; + uLong fileNameBufferSize; + void *extraField; + uLong extraFieldBufferSize; + char *szComment; + uLong commentBufferSize; +{ + return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL, + szFileName,fileNameBufferSize, + extraField,extraFieldBufferSize, + szComment,commentBufferSize); +} + +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ +extern int ZEXPORT unzGoToFirstFile (file) + unzFile file; +{ + int err=UNZ_OK; + unz_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + s->pos_in_central_dir=s->offset_central_dir; + s->num_file=0; + err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ +extern int ZEXPORT unzGoToNextFile (file) + unzFile file; +{ + unz_s* s; + int err; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */ + if (s->num_file+1==s->gi.number_entry) + return UNZ_END_OF_LIST_OF_FILE; + + s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + + s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; + s->num_file++; + err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + + +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzipStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ +extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity) + unzFile file; + const char *szFileName; + int iCaseSensitivity; +{ + unz_s* s; + int err; + + /* We remember the 'current' position in the file so that we can jump + * back there if we fail. + */ + unz_file_info cur_file_infoSaved; + unz_file_info_internal cur_file_info_internalSaved; + uLong num_fileSaved; + uLong pos_in_central_dirSaved; + + + if (file==NULL) + return UNZ_PARAMERROR; + + if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) + return UNZ_PARAMERROR; + + s=(unz_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + + /* Save the current state */ + num_fileSaved = s->num_file; + pos_in_central_dirSaved = s->pos_in_central_dir; + cur_file_infoSaved = s->cur_file_info; + cur_file_info_internalSaved = s->cur_file_info_internal; + + err = unzGoToFirstFile(file); + + while (err == UNZ_OK) + { + char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; + err = unzGetCurrentFileInfo(file,NULL, + szCurrentFileName,sizeof(szCurrentFileName)-1, + NULL,0,NULL,0); + if (err == UNZ_OK) + { + if (unzStringFileNameCompare(szCurrentFileName, + szFileName,iCaseSensitivity)==0) + return UNZ_OK; + err = unzGoToNextFile(file); + } + } + + /* We failed, so restore the state of the 'current file' to where we + * were. + */ + s->num_file = num_fileSaved ; + s->pos_in_central_dir = pos_in_central_dirSaved ; + s->cur_file_info = cur_file_infoSaved; + s->cur_file_info_internal = cur_file_info_internalSaved; + return err; +} + + +/* +/////////////////////////////////////////// +// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net) +// I need random access +// +// Further optimization could be realized by adding an ability +// to cache the directory in memory. The goal being a single +// comprehensive file read to put the file I need in a memory. +*/ + +/* +typedef struct unz_file_pos_s +{ + uLong pos_in_zip_directory; // offset in file + uLong num_of_file; // # of file +} unz_file_pos; +*/ + +extern int ZEXPORT unzGetFilePos(file, file_pos) + unzFile file; + unz_file_pos* file_pos; +{ + unz_s* s; + + if (file==NULL || file_pos==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + + file_pos->pos_in_zip_directory = s->pos_in_central_dir; + file_pos->num_of_file = s->num_file; + + return UNZ_OK; +} + +extern int ZEXPORT unzGoToFilePos(file, file_pos) + unzFile file; + unz_file_pos* file_pos; +{ + unz_s* s; + int err; + + if (file==NULL || file_pos==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + + /* jump to the right spot */ + s->pos_in_central_dir = file_pos->pos_in_zip_directory; + s->num_file = file_pos->num_of_file; + + /* set the current file */ + err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + /* return results */ + s->current_file_ok = (err == UNZ_OK); + return err; +} + +/* +// Unzip Helper Functions - should be here? +/////////////////////////////////////////// +*/ + +/* + Read the local header of the current zipfile + Check the coherency of the local header and info in the end of central + directory about this file + store in *piSizeVar the size of extra info in local header + (filename and size of extra field data) +*/ +local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar, + poffset_local_extrafield, + psize_local_extrafield) + unz_s* s; + uInt* piSizeVar; + uLong *poffset_local_extrafield; + uInt *psize_local_extrafield; +{ + uLong uMagic,uData,uFlags; + uLong size_filename; + uLong size_extra_field; + int err=UNZ_OK; + + *piSizeVar = 0; + *poffset_local_extrafield = 0; + *psize_local_extrafield = 0; + + if (ZSEEK(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile + + s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + + if (err==UNZ_OK) + { + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x04034b50) + err=UNZ_BADZIPFILE; + } + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) + err=UNZ_ERRNO; +/* + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) + err=UNZ_BADZIPFILE; +*/ + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) + err=UNZ_BADZIPFILE; + + if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && + (s->cur_file_info.compression_method!=Z_DEFLATED)) + err=UNZ_BADZIPFILE; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */ + err=UNZ_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) + err=UNZ_BADZIPFILE; + + *piSizeVar += (uInt)size_filename; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK) + err=UNZ_ERRNO; + *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + + SIZEZIPLOCALHEADER + size_filename; + *psize_local_extrafield = (uInt)size_extra_field; + + *piSizeVar += (uInt)size_extra_field; + + return err; +} + +/* + Open for reading data the current file in the zipfile. + If there is no error and the file is opened, the return value is UNZ_OK. +*/ +extern int ZEXPORT unzOpenCurrentFile3 (file, method, level, raw, password) + unzFile file; + int* method; + int* level; + int raw; + const char* password; +{ + int err=UNZ_OK; + uInt iSizeVar; + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + uLong offset_local_extrafield; /* offset of the local extra field */ + uInt size_local_extrafield; /* size of the local extra field */ +# ifndef NOUNCRYPT + char source[12]; +# else + if (password != NULL) + return UNZ_PARAMERROR; +# endif + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (!s->current_file_ok) + return UNZ_PARAMERROR; + + if (s->pfile_in_zip_read != NULL) + unzCloseCurrentFile(file); + + if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar, + &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) + return UNZ_BADZIPFILE; + + pfile_in_zip_read_info = (file_in_zip_read_info_s*) + ALLOC(sizeof(file_in_zip_read_info_s)); + if (pfile_in_zip_read_info==NULL) + return UNZ_INTERNALERROR; + + pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); + pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; + pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; + pfile_in_zip_read_info->pos_local_extrafield=0; + pfile_in_zip_read_info->raw=raw; + + if (pfile_in_zip_read_info->read_buffer==NULL) + { + TRYFREE(pfile_in_zip_read_info); + return UNZ_INTERNALERROR; + } + + pfile_in_zip_read_info->stream_initialised=0; + + if (method!=NULL) + *method = (int)s->cur_file_info.compression_method; + + if (level!=NULL) + { + *level = 6; + switch (s->cur_file_info.flag & 0x06) + { + case 6 : *level = 1; break; + case 4 : *level = 2; break; + case 2 : *level = 9; break; + } + } + + if ((s->cur_file_info.compression_method!=0) && + (s->cur_file_info.compression_method!=Z_DEFLATED)) + err=UNZ_BADZIPFILE; + + pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; + pfile_in_zip_read_info->crc32=0; + pfile_in_zip_read_info->compression_method = + s->cur_file_info.compression_method; + pfile_in_zip_read_info->filestream=s->filestream; + pfile_in_zip_read_info->z_filefunc=s->z_filefunc; + pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; + + pfile_in_zip_read_info->stream.total_out = 0; + + if ((s->cur_file_info.compression_method==Z_DEFLATED) && + (!raw)) + { + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; + pfile_in_zip_read_info->stream.opaque = (voidpf)0; + pfile_in_zip_read_info->stream.next_in = (voidpf)0; + pfile_in_zip_read_info->stream.avail_in = 0; + + err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); + if (err == Z_OK) + pfile_in_zip_read_info->stream_initialised=1; + else + { + TRYFREE(pfile_in_zip_read_info); + return err; + } + /* windowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. + * In unzip, i don't wait absolutely Z_STREAM_END because I known the + * size of both compressed and uncompressed data + */ + } + pfile_in_zip_read_info->rest_read_compressed = + s->cur_file_info.compressed_size ; + pfile_in_zip_read_info->rest_read_uncompressed = + s->cur_file_info.uncompressed_size ; + + + pfile_in_zip_read_info->pos_in_zipfile = + s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + + iSizeVar; + + pfile_in_zip_read_info->stream.avail_in = (uInt)0; + + s->pfile_in_zip_read = pfile_in_zip_read_info; + +# ifndef NOUNCRYPT + if (password != NULL) + { + int i; + s->pcrc_32_tab = get_crc_table(); + init_keys(password,s->keys,s->pcrc_32_tab); + if (ZSEEK(s->z_filefunc, s->filestream, + s->pfile_in_zip_read->pos_in_zipfile + + s->pfile_in_zip_read->byte_before_the_zipfile, + SEEK_SET)!=0) + return UNZ_INTERNALERROR; + if(ZREAD(s->z_filefunc, s->filestream,source, 12)<12) + return UNZ_INTERNALERROR; + + for (i = 0; i<12; i++) + zdecode(s->keys,s->pcrc_32_tab,source[i]); + + s->pfile_in_zip_read->pos_in_zipfile+=12; + s->encrypted=1; + } +# endif + + + return UNZ_OK; +} + +extern int ZEXPORT unzOpenCurrentFile (file) + unzFile file; +{ + return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); +} + +extern int ZEXPORT unzOpenCurrentFilePassword (file, password) + unzFile file; + const char* password; +{ + return unzOpenCurrentFile3(file, NULL, NULL, 0, password); +} + +extern int ZEXPORT unzOpenCurrentFile2 (file,method,level,raw) + unzFile file; + int* method; + int* level; + int raw; +{ + return unzOpenCurrentFile3(file, method, level, raw, NULL); +} + +/* + Read bytes from the current file. + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ +extern int ZEXPORT unzReadCurrentFile (file, buf, len) + unzFile file; + voidp buf; + unsigned len; +{ + int err=UNZ_OK; + uInt iRead = 0; + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if (pfile_in_zip_read_info->read_buffer == NULL) + return UNZ_END_OF_LIST_OF_FILE; + if (len==0) + return 0; + + pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; + + pfile_in_zip_read_info->stream.avail_out = (uInt)len; + + if ((len>pfile_in_zip_read_info->rest_read_uncompressed) && + (!(pfile_in_zip_read_info->raw))) + pfile_in_zip_read_info->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_uncompressed; + + if ((len>pfile_in_zip_read_info->rest_read_compressed+ + pfile_in_zip_read_info->stream.avail_in) && + (pfile_in_zip_read_info->raw)) + pfile_in_zip_read_info->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_compressed+ + pfile_in_zip_read_info->stream.avail_in; + + while (pfile_in_zip_read_info->stream.avail_out>0) + { + if ((pfile_in_zip_read_info->stream.avail_in==0) && + (pfile_in_zip_read_info->rest_read_compressed>0)) + { + uInt uReadThis = UNZ_BUFSIZE; + if (pfile_in_zip_read_info->rest_read_compressedrest_read_compressed; + if (uReadThis == 0) + return UNZ_EOF; + if (ZSEEK(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->pos_in_zipfile + + pfile_in_zip_read_info->byte_before_the_zipfile, + ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + if (ZREAD(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->read_buffer, + uReadThis)!=uReadThis) + return UNZ_ERRNO; + + +# ifndef NOUNCRYPT + if(s->encrypted) + { + uInt i; + for(i=0;iread_buffer[i] = + zdecode(s->keys,s->pcrc_32_tab, + pfile_in_zip_read_info->read_buffer[i]); + } +# endif + + + pfile_in_zip_read_info->pos_in_zipfile += uReadThis; + + pfile_in_zip_read_info->rest_read_compressed-=uReadThis; + + pfile_in_zip_read_info->stream.next_in = + (Bytef*)pfile_in_zip_read_info->read_buffer; + pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; + } + + if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw)) + { + uInt uDoCopy,i ; + + if ((pfile_in_zip_read_info->stream.avail_in == 0) && + (pfile_in_zip_read_info->rest_read_compressed == 0)) + return (iRead==0) ? UNZ_EOF : iRead; + + if (pfile_in_zip_read_info->stream.avail_out < + pfile_in_zip_read_info->stream.avail_in) + uDoCopy = pfile_in_zip_read_info->stream.avail_out ; + else + uDoCopy = pfile_in_zip_read_info->stream.avail_in ; + + for (i=0;istream.next_out+i) = + *(pfile_in_zip_read_info->stream.next_in+i); + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, + pfile_in_zip_read_info->stream.next_out, + uDoCopy); + pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; + pfile_in_zip_read_info->stream.avail_in -= uDoCopy; + pfile_in_zip_read_info->stream.avail_out -= uDoCopy; + pfile_in_zip_read_info->stream.next_out += uDoCopy; + pfile_in_zip_read_info->stream.next_in += uDoCopy; + pfile_in_zip_read_info->stream.total_out += uDoCopy; + iRead += uDoCopy; + } + else + { + uLong uTotalOutBefore,uTotalOutAfter; + const Bytef *bufBefore; + uLong uOutThis; + int flush=Z_SYNC_FLUSH; + + uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; + bufBefore = pfile_in_zip_read_info->stream.next_out; + + /* + if ((pfile_in_zip_read_info->rest_read_uncompressed == + pfile_in_zip_read_info->stream.avail_out) && + (pfile_in_zip_read_info->rest_read_compressed == 0)) + flush = Z_FINISH; + */ + err=inflate(&pfile_in_zip_read_info->stream,flush); + + if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL)) + err = Z_DATA_ERROR; + + uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; + uOutThis = uTotalOutAfter-uTotalOutBefore; + + pfile_in_zip_read_info->crc32 = + crc32(pfile_in_zip_read_info->crc32,bufBefore, + (uInt)(uOutThis)); + + pfile_in_zip_read_info->rest_read_uncompressed -= + uOutThis; + + iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); + + if (err==Z_STREAM_END) + return (iRead==0) ? UNZ_EOF : iRead; + if (err!=Z_OK) + break; + } + } + + if (err==Z_OK) + return iRead; + return err; +} + + +/* + Give the current position in uncompressed data +*/ +extern z_off_t ZEXPORT unztell (file) + unzFile file; +{ + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + return (z_off_t)pfile_in_zip_read_info->stream.total_out; +} + + +/* + return 1 if the end of file was reached, 0 elsewhere +*/ +extern int ZEXPORT unzeof (file) + unzFile file; +{ + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + if (pfile_in_zip_read_info->rest_read_uncompressed == 0) + return 1; + else + return 0; +} + + + +/* + Read extra field from the current file (opened by unzOpenCurrentFile) + This is the local-header version of the extra field (sometimes, there is + more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field that can be read + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ +extern int ZEXPORT unzGetLocalExtrafield (file,buf,len) + unzFile file; + voidp buf; + unsigned len; +{ + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + uInt read_now; + uLong size_to_read; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + size_to_read = (pfile_in_zip_read_info->size_local_extrafield - + pfile_in_zip_read_info->pos_local_extrafield); + + if (buf==NULL) + return (int)size_to_read; + + if (len>size_to_read) + read_now = (uInt)size_to_read; + else + read_now = (uInt)len ; + + if (read_now==0) + return 0; + + if (ZSEEK(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->offset_local_extrafield + + pfile_in_zip_read_info->pos_local_extrafield, + ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + if (ZREAD(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + buf,read_now)!=read_now) + return UNZ_ERRNO; + + return (int)read_now; +} + +/* + Close the file in zip opened with unzipOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ +extern int ZEXPORT unzCloseCurrentFile (file) + unzFile file; +{ + int err=UNZ_OK; + + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && + (!pfile_in_zip_read_info->raw)) + { + if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) + err=UNZ_CRCERROR; + } + + + TRYFREE(pfile_in_zip_read_info->read_buffer); + pfile_in_zip_read_info->read_buffer = NULL; + if (pfile_in_zip_read_info->stream_initialised) + inflateEnd(&pfile_in_zip_read_info->stream); + + pfile_in_zip_read_info->stream_initialised = 0; + TRYFREE(pfile_in_zip_read_info); + + s->pfile_in_zip_read=NULL; + + return err; +} + + +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ +extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf) + unzFile file; + char *szComment; + uLong uSizeBuf; +{ + unz_s* s; + uLong uReadThis ; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + + uReadThis = uSizeBuf; + if (uReadThis>s->gi.size_comment) + uReadThis = s->gi.size_comment; + + if (ZSEEK(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + if (uReadThis>0) + { + *szComment='\0'; + if (ZREAD(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis) + return UNZ_ERRNO; + } + + if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) + *(szComment+s->gi.size_comment)='\0'; + return (int)uReadThis; +} + +/* Additions by RX '2004 */ +extern uLong ZEXPORT unzGetOffset (file) + unzFile file; +{ + unz_s* s; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (!s->current_file_ok) + return 0; + if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff) + if (s->num_file==s->gi.number_entry) + return 0; + return s->pos_in_central_dir; +} + +extern int ZEXPORT unzSetOffset (file, pos) + unzFile file; + uLong pos; +{ + unz_s* s; + int err; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + + s->pos_in_central_dir = pos; + s->num_file = s->gi.number_entry; /* hack */ + err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} diff --git a/contrib/unzip/unzip.h b/contrib/unzip/unzip.h index 16fd9fd70..e3b7f24ee 100644 --- a/contrib/unzip/unzip.h +++ b/contrib/unzip/unzip.h @@ -1,358 +1,358 @@ -/* unzip.h -- IO for uncompress .zip files using zlib - Version 1.01e, February 12th, 2005 - - Copyright (C) 1998-2005 Gilles Vollant - - This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g - WinZip, InfoZip tools and compatible. - - Multi volume ZipFile (span) are not supported. - Encryption compatible with pkzip 2.04g only supported - Old compressions used by old PKZip 1.x are not supported - - - I WAIT FEEDBACK at mail info@winimage.com - Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution - - Condition of use and distribution are the same than zlib : - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - -*/ - -/* for more info about .ZIP format, see - http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip - http://www.info-zip.org/pub/infozip/doc/ - PkWare has also a specification at : - ftp://ftp.pkware.com/probdesc.zip -*/ - -#ifndef _unz_H -#define _unz_H - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _ZLIB_H -# ifdef ASSIMP_BUILD_NO_OWN_ZLIB -# include -# else -# include "../zlib/zlib.h" -# endif -#endif - -#ifndef _ZLIBIOAPI_H -#include "ioapi.h" -#endif - -#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) -/* like the STRICT of WIN32, we define a pointer that cannot be converted - from (void*) without cast */ -typedef struct TagunzFile__ { int unused; } unzFile__; -typedef unzFile__ *unzFile; -#else -typedef voidp unzFile; -#endif - - -#define UNZ_OK (0) -#define UNZ_END_OF_LIST_OF_FILE (-100) -#define UNZ_ERRNO (Z_ERRNO) -#define UNZ_EOF (0) -#define UNZ_PARAMERROR (-102) -#define UNZ_BADZIPFILE (-103) -#define UNZ_INTERNALERROR (-104) -#define UNZ_CRCERROR (-105) - -/* tm_unz contain date/time info */ -typedef struct tm_unz_s -{ - uInt tm_sec; /* seconds after the minute - [0,59] */ - uInt tm_min; /* minutes after the hour - [0,59] */ - uInt tm_hour; /* hours since midnight - [0,23] */ - uInt tm_mday; /* day of the month - [1,31] */ - uInt tm_mon; /* months since January - [0,11] */ - uInt tm_year; /* years - [1980..2044] */ -} tm_unz; - -/* unz_global_info structure contain global data about the ZIPfile - These data comes from the end of central dir */ -typedef struct unz_global_info_s -{ - uLong number_entry; /* total number of entries in - the central dir on this disk */ - uLong size_comment; /* size of the global comment of the zipfile */ -} unz_global_info; - - -/* unz_file_info contain information about a file in the zipfile */ -typedef struct unz_file_info_s -{ - uLong version; /* version made by 2 bytes */ - uLong version_needed; /* version needed to extract 2 bytes */ - uLong flag; /* general purpose bit flag 2 bytes */ - uLong compression_method; /* compression method 2 bytes */ - uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ - uLong crc; /* crc-32 4 bytes */ - uLong compressed_size; /* compressed size 4 bytes */ - uLong uncompressed_size; /* uncompressed size 4 bytes */ - uLong size_filename; /* filename length 2 bytes */ - uLong size_file_extra; /* extra field length 2 bytes */ - uLong size_file_comment; /* file comment length 2 bytes */ - - uLong disk_num_start; /* disk number start 2 bytes */ - uLong internal_fa; /* internal file attributes 2 bytes */ - uLong external_fa; /* external file attributes 4 bytes */ - - tm_unz tmu_date; -} unz_file_info; - -extern int ZEXPORT unzStringFileNameCompare (const char* fileName1, - const char* fileName2, - int iCaseSensitivity); -/* - Compare two filename (fileName1,fileName2). - If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) - If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi - or strcasecmp) - If iCaseSenisivity = 0, case sensitivity is defaut of your operating system - (like 1 on Unix, 2 on Windows) -*/ - - -extern unzFile ZEXPORT unzOpen (const char *path); -/* - Open a Zip file. path contain the full pathname (by example, - on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer - "zlib/zlib113.zip". - If the zipfile cannot be opened (file don't exist or in not valid), the - return value is NULL. - Else, the return value is a unzFile Handle, usable with other function - of this unzip package. -*/ - -extern unzFile ZEXPORT unzOpen2 (const char *path, - zlib_filefunc_def* pzlib_filefunc_def); -/* - Open a Zip file, like unzOpen, but provide a set of file low level API - for read/write the zip file (see ioapi.h) -*/ - -extern int ZEXPORT unzClose (unzFile file); -/* - Close a ZipFile opened with unzipOpen. - If there is files inside the .Zip opened with unzOpenCurrentFile (see later), - these files MUST be closed with unzipCloseCurrentFile before call unzipClose. - return UNZ_OK if there is no problem. */ - -extern int ZEXPORT unzGetGlobalInfo (unzFile file, - unz_global_info *pglobal_info); -/* - Write info about the ZipFile in the *pglobal_info structure. - No preparation of the structure is needed - return UNZ_OK if there is no problem. */ - - -extern int ZEXPORT unzGetGlobalComment (unzFile file, - char *szComment, - uLong uSizeBuf); -/* - Get the global comment string of the ZipFile, in the szComment buffer. - uSizeBuf is the size of the szComment buffer. - return the number of byte copied or an error code <0 -*/ - - -/***************************************************************************/ -/* Unzip package allow you browse the directory of the zipfile */ - -extern int ZEXPORT unzGoToFirstFile (unzFile file); -/* - Set the current file of the zipfile to the first file. - return UNZ_OK if there is no problem -*/ - -extern int ZEXPORT unzGoToNextFile (unzFile file); -/* - Set the current file of the zipfile to the next file. - return UNZ_OK if there is no problem - return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. -*/ - -extern int ZEXPORT unzLocateFile (unzFile file, - const char *szFileName, - int iCaseSensitivity); -/* - Try locate the file szFileName in the zipfile. - For the iCaseSensitivity signification, see unzStringFileNameCompare - - return value : - UNZ_OK if the file is found. It becomes the current file. - UNZ_END_OF_LIST_OF_FILE if the file is not found -*/ - - -/* ****************************************** */ -/* Ryan supplied functions */ -/* unz_file_info contain information about a file in the zipfile */ -typedef struct unz_file_pos_s -{ - uLong pos_in_zip_directory; /* offset in zip file directory */ - uLong num_of_file; /* # of file */ -} unz_file_pos; - -extern int ZEXPORT unzGetFilePos( - unzFile file, - unz_file_pos* file_pos); - -extern int ZEXPORT unzGoToFilePos( - unzFile file, - unz_file_pos* file_pos); - -/* ****************************************** */ - -extern int ZEXPORT unzGetCurrentFileInfo (unzFile file, - unz_file_info *pfile_info, - char *szFileName, - uLong fileNameBufferSize, - void *extraField, - uLong extraFieldBufferSize, - char *szComment, - uLong commentBufferSize); -/* - Get Info about the current file - if pfile_info!=NULL, the *pfile_info structure will contain somes info about - the current file - if szFileName!=NULL, the filemane string will be copied in szFileName - (fileNameBufferSize is the size of the buffer) - if extraField!=NULL, the extra field information will be copied in extraField - (extraFieldBufferSize is the size of the buffer). - This is the Central-header version of the extra field - if szComment!=NULL, the comment string of the file will be copied in szComment - (commentBufferSize is the size of the buffer) -*/ - -/***************************************************************************/ -/* for reading the content of the current zipfile, you can open it, read data - from it, and close it (you can close it before reading all the file) - */ - -extern int ZEXPORT unzOpenCurrentFile (unzFile file); -/* - Open for reading data the current file in the zipfile. - If there is no error, the return value is UNZ_OK. -*/ - -extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, - const char* password); -/* - Open for reading data the current file in the zipfile. - password is a crypting password - If there is no error, the return value is UNZ_OK. -*/ - -extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, - int* method, - int* level, - int raw); -/* - Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) - if raw==1 - *method will receive method of compression, *level will receive level of - compression - note : you can set level parameter as NULL (if you did not want known level, - but you CANNOT set method parameter as NULL -*/ - -extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, - int* method, - int* level, - int raw, - const char* password); -/* - Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) - if raw==1 - *method will receive method of compression, *level will receive level of - compression - note : you can set level parameter as NULL (if you did not want known level, - but you CANNOT set method parameter as NULL -*/ - - -extern int ZEXPORT unzCloseCurrentFile (unzFile file); -/* - Close the file in zip opened with unzOpenCurrentFile - Return UNZ_CRCERROR if all the file was read but the CRC is not good -*/ - -extern int ZEXPORT unzReadCurrentFile (unzFile file, - voidp buf, - unsigned len); -/* - Read bytes from the current file (opened by unzOpenCurrentFile) - buf contain buffer where data must be copied - len the size of buf. - - return the number of byte copied if somes bytes are copied - return 0 if the end of file was reached - return <0 with error code if there is an error - (UNZ_ERRNO for IO error, or zLib error for uncompress error) -*/ - -extern z_off_t ZEXPORT unztell (unzFile file); -/* - Give the current position in uncompressed data -*/ - -extern int ZEXPORT unzeof (unzFile file); -/* - return 1 if the end of file was reached, 0 elsewhere -*/ - -extern int ZEXPORT unzGetLocalExtrafield (unzFile file, - voidp buf, - unsigned len); -/* - Read extra field from the current file (opened by unzOpenCurrentFile) - This is the local-header version of the extra field (sometimes, there is - more info in the local-header version than in the central-header) - - if buf==NULL, it return the size of the local extra field - - if buf!=NULL, len is the size of the buffer, the extra header is copied in - buf. - the return value is the number of bytes copied in buf, or (if <0) - the error code -*/ - -/***************************************************************************/ - -/* Get the current file offset */ -extern uLong ZEXPORT unzGetOffset (unzFile file); - -/* Set the current file offset */ -extern int ZEXPORT unzSetOffset (unzFile file, uLong pos); - - - -#ifdef __cplusplus -} -#endif - -#endif /* _unz_H */ +/* unzip.h -- IO for uncompress .zip files using zlib + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant + + This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g + WinZip, InfoZip tools and compatible. + + Multi volume ZipFile (span) are not supported. + Encryption compatible with pkzip 2.04g only supported + Old compressions used by old PKZip 1.x are not supported + + + I WAIT FEEDBACK at mail info@winimage.com + Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution + + Condition of use and distribution are the same than zlib : + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + +*/ + +/* for more info about .ZIP format, see + http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip + http://www.info-zip.org/pub/infozip/doc/ + PkWare has also a specification at : + ftp://ftp.pkware.com/probdesc.zip +*/ + +#ifndef _unz_H +#define _unz_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _ZLIB_H +# ifdef ASSIMP_BUILD_NO_OWN_ZLIB +# include +# else +# include "../zlib/zlib.h" +# endif +#endif + +#ifndef _ZLIBIOAPI_H +#include "ioapi.h" +#endif + +#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) +/* like the STRICT of WIN32, we define a pointer that cannot be converted + from (void*) without cast */ +typedef struct TagunzFile__ { int unused; } unzFile__; +typedef unzFile__ *unzFile; +#else +typedef voidp unzFile; +#endif + + +#define UNZ_OK (0) +#define UNZ_END_OF_LIST_OF_FILE (-100) +#define UNZ_ERRNO (Z_ERRNO) +#define UNZ_EOF (0) +#define UNZ_PARAMERROR (-102) +#define UNZ_BADZIPFILE (-103) +#define UNZ_INTERNALERROR (-104) +#define UNZ_CRCERROR (-105) + +/* tm_unz contain date/time info */ +typedef struct tm_unz_s +{ + uInt tm_sec; /* seconds after the minute - [0,59] */ + uInt tm_min; /* minutes after the hour - [0,59] */ + uInt tm_hour; /* hours since midnight - [0,23] */ + uInt tm_mday; /* day of the month - [1,31] */ + uInt tm_mon; /* months since January - [0,11] */ + uInt tm_year; /* years - [1980..2044] */ +} tm_unz; + +/* unz_global_info structure contain global data about the ZIPfile + These data comes from the end of central dir */ +typedef struct unz_global_info_s +{ + uLong number_entry; /* total number of entries in + the central dir on this disk */ + uLong size_comment; /* size of the global comment of the zipfile */ +} unz_global_info; + + +/* unz_file_info contain information about a file in the zipfile */ +typedef struct unz_file_info_s +{ + uLong version; /* version made by 2 bytes */ + uLong version_needed; /* version needed to extract 2 bytes */ + uLong flag; /* general purpose bit flag 2 bytes */ + uLong compression_method; /* compression method 2 bytes */ + uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ + uLong crc; /* crc-32 4 bytes */ + uLong compressed_size; /* compressed size 4 bytes */ + uLong uncompressed_size; /* uncompressed size 4 bytes */ + uLong size_filename; /* filename length 2 bytes */ + uLong size_file_extra; /* extra field length 2 bytes */ + uLong size_file_comment; /* file comment length 2 bytes */ + + uLong disk_num_start; /* disk number start 2 bytes */ + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ + + tm_unz tmu_date; +} unz_file_info; + +extern int ZEXPORT unzStringFileNameCompare (const char* fileName1, + const char* fileName2, + int iCaseSensitivity); +/* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) +*/ + + +extern unzFile ZEXPORT unzOpen (const char *path); +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer + "zlib/zlib113.zip". + If the zipfile cannot be opened (file don't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. +*/ + +extern unzFile ZEXPORT unzOpen2 (const char *path, + zlib_filefunc_def* pzlib_filefunc_def); +/* + Open a Zip file, like unzOpen, but provide a set of file low level API + for read/write the zip file (see ioapi.h) +*/ + +extern int ZEXPORT unzClose (unzFile file); +/* + Close a ZipFile opened with unzipOpen. + If there is files inside the .Zip opened with unzOpenCurrentFile (see later), + these files MUST be closed with unzipCloseCurrentFile before call unzipClose. + return UNZ_OK if there is no problem. */ + +extern int ZEXPORT unzGetGlobalInfo (unzFile file, + unz_global_info *pglobal_info); +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ + + +extern int ZEXPORT unzGetGlobalComment (unzFile file, + char *szComment, + uLong uSizeBuf); +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ + + +/***************************************************************************/ +/* Unzip package allow you browse the directory of the zipfile */ + +extern int ZEXPORT unzGoToFirstFile (unzFile file); +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ + +extern int ZEXPORT unzGoToNextFile (unzFile file); +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ + +extern int ZEXPORT unzLocateFile (unzFile file, + const char *szFileName, + int iCaseSensitivity); +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ + + +/* ****************************************** */ +/* Ryan supplied functions */ +/* unz_file_info contain information about a file in the zipfile */ +typedef struct unz_file_pos_s +{ + uLong pos_in_zip_directory; /* offset in zip file directory */ + uLong num_of_file; /* # of file */ +} unz_file_pos; + +extern int ZEXPORT unzGetFilePos( + unzFile file, + unz_file_pos* file_pos); + +extern int ZEXPORT unzGoToFilePos( + unzFile file, + unz_file_pos* file_pos); + +/* ****************************************** */ + +extern int ZEXPORT unzGetCurrentFileInfo (unzFile file, + unz_file_info *pfile_info, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize); +/* + Get Info about the current file + if pfile_info!=NULL, the *pfile_info structure will contain somes info about + the current file + if szFileName!=NULL, the filemane string will be copied in szFileName + (fileNameBufferSize is the size of the buffer) + if extraField!=NULL, the extra field information will be copied in extraField + (extraFieldBufferSize is the size of the buffer). + This is the Central-header version of the extra field + if szComment!=NULL, the comment string of the file will be copied in szComment + (commentBufferSize is the size of the buffer) +*/ + +/***************************************************************************/ +/* for reading the content of the current zipfile, you can open it, read data + from it, and close it (you can close it before reading all the file) + */ + +extern int ZEXPORT unzOpenCurrentFile (unzFile file); +/* + Open for reading data the current file in the zipfile. + If there is no error, the return value is UNZ_OK. +*/ + +extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, + const char* password); +/* + Open for reading data the current file in the zipfile. + password is a crypting password + If there is no error, the return value is UNZ_OK. +*/ + +extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, + int* method, + int* level, + int raw); +/* + Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) + if raw==1 + *method will receive method of compression, *level will receive level of + compression + note : you can set level parameter as NULL (if you did not want known level, + but you CANNOT set method parameter as NULL +*/ + +extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, + int* method, + int* level, + int raw, + const char* password); +/* + Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) + if raw==1 + *method will receive method of compression, *level will receive level of + compression + note : you can set level parameter as NULL (if you did not want known level, + but you CANNOT set method parameter as NULL +*/ + + +extern int ZEXPORT unzCloseCurrentFile (unzFile file); +/* + Close the file in zip opened with unzOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ + +extern int ZEXPORT unzReadCurrentFile (unzFile file, + voidp buf, + unsigned len); +/* + Read bytes from the current file (opened by unzOpenCurrentFile) + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ + +extern z_off_t ZEXPORT unztell (unzFile file); +/* + Give the current position in uncompressed data +*/ + +extern int ZEXPORT unzeof (unzFile file); +/* + return 1 if the end of file was reached, 0 elsewhere +*/ + +extern int ZEXPORT unzGetLocalExtrafield (unzFile file, + voidp buf, + unsigned len); +/* + Read extra field from the current file (opened by unzOpenCurrentFile) + This is the local-header version of the extra field (sometimes, there is + more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ + +/***************************************************************************/ + +/* Get the current file offset */ +extern uLong ZEXPORT unzGetOffset (unzFile file); + +/* Set the current file offset */ +extern int ZEXPORT unzSetOffset (unzFile file, uLong pos); + + + +#ifdef __cplusplus +} +#endif + +#endif /* _unz_H */ diff --git a/contrib/zlib/CMakeLists.txt b/contrib/zlib/CMakeLists.txt index 5a9546038..022d3dfba 100644 --- a/contrib/zlib/CMakeLists.txt +++ b/contrib/zlib/CMakeLists.txt @@ -1,199 +1,199 @@ -cmake_minimum_required(VERSION 2.4.4) -set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON) - -# CMake 3.0 changed the project command, setting policy CMP0048 reverts to the old behaviour. -# See http://www.cmake.org/cmake/help/v3.0/policy/CMP0048.html -cmake_policy(PUSH) -if(CMAKE_MAJOR_VERSION GREATER 2) - cmake_policy(SET CMP0048 OLD) -endif() -project(zlib C) -cmake_policy(POP) - -set(VERSION "1.2.8") - -option(ASM686 "Enable building i686 assembly implementation for zlib") -option(AMD64 "Enable building amd64 assembly implementation for zlib") - -#set(INSTALL_BIN_DIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Installation directory for executables") -#set(INSTALL_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib" CACHE PATH "Installation directory for libraries") -#set(INSTALL_INC_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH "Installation directory for headers") -#set(INSTALL_MAN_DIR "${CMAKE_INSTALL_PREFIX}/share/man" CACHE PATH "Installation directory for manual pages") -#set(INSTALL_PKGCONFIG_DIR "${CMAKE_INSTALL_PREFIX}/share/pkgconfig" CACHE PATH "Installation directory for pkgconfig (.pc) files") - -include(CheckTypeSize) -include(CheckFunctionExists) -include(CheckIncludeFile) -include(CheckCSourceCompiles) -enable_testing() - -check_include_file(sys/types.h HAVE_SYS_TYPES_H) -check_include_file(stdint.h HAVE_STDINT_H) -check_include_file(stddef.h HAVE_STDDEF_H) - -# -# Check to see if we have large file support -# -set(CMAKE_REQUIRED_DEFINITIONS -D_LARGEFILE64_SOURCE=1) -# We add these other definitions here because CheckTypeSize.cmake -# in CMake 2.4.x does not automatically do so and we want -# compatibility with CMake 2.4.x. -if(HAVE_SYS_TYPES_H) - list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_SYS_TYPES_H) -endif() -if(HAVE_STDINT_H) - list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDINT_H) -endif() -if(HAVE_STDDEF_H) - list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDDEF_H) -endif() -check_type_size(off64_t OFF64_T) -if(HAVE_OFF64_T) - add_definitions(-D_LARGEFILE64_SOURCE=1) -endif() -set(CMAKE_REQUIRED_DEFINITIONS) # clear variable - -# -# Check for fseeko -# -check_function_exists(fseeko HAVE_FSEEKO) -if(NOT HAVE_FSEEKO) - add_definitions(-DNO_FSEEKO) -endif() - -# -# Check for unistd.h -# -check_include_file(unistd.h Z_HAVE_UNISTD_H) - -if(MSVC) - set(CMAKE_DEBUG_POSTFIX "d") - add_definitions(-D_CRT_SECURE_NO_DEPRECATE) - add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE) - include_directories(${CMAKE_CURRENT_SOURCE_DIR}) -endif() - -if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR) - # If we're doing an out of source build and the user has a zconf.h - # in their source tree... - if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h) - message(STATUS "Renaming") - message(STATUS " ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h") - message(STATUS "to 'zconf.h.included' because this file is included with zlib") - message(STATUS "but CMake generates it automatically in the build directory.") - file(RENAME ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.included) - endif() -endif() - -set(ZLIB_PC ${CMAKE_CURRENT_BINARY_DIR}/zlib.pc) -configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/zlib.pc.cmakein - ${ZLIB_PC} @ONLY) -configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.cmakein - ${CMAKE_CURRENT_BINARY_DIR}/zconf.h @ONLY) - -include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}) - - -#============================================================================ -# zlib -#============================================================================ - -set(ZLIB_PUBLIC_HDRS - ${CMAKE_CURRENT_BINARY_DIR}/zconf.h - zlib.h -) -set(ZLIB_PRIVATE_HDRS - crc32.h - deflate.h - gzguts.h - inffast.h - inffixed.h - inflate.h - inftrees.h - trees.h - zutil.h -) -set(ZLIB_SRCS - adler32.c - compress.c - crc32.c - deflate.c - gzclose.c - gzlib.c - gzread.c - gzwrite.c - inflate.c - infback.c - inftrees.c - inffast.c - trees.c - uncompr.c - zutil.c -) - -if(NOT MINGW) - set(ZLIB_DLL_SRCS - win32/zlib1.rc # If present will override custom build rule below. - ) -endif() - -if(CMAKE_COMPILER_IS_GNUCC) - if(ASM686) - set(ZLIB_ASMS contrib/asm686/match.S) - elseif (AMD64) - set(ZLIB_ASMS contrib/amd64/amd64-match.S) - endif () - - if(ZLIB_ASMS) - add_definitions(-DASMV) - set_source_files_properties(${ZLIB_ASMS} PROPERTIES LANGUAGE C COMPILE_FLAGS -DNO_UNDERLINE) - endif() -endif() - -if(MSVC) - if(ASM686) - ENABLE_LANGUAGE(ASM_MASM) - set(ZLIB_ASMS - contrib/masmx86/inffas32.asm - contrib/masmx86/match686.asm - ) - elseif (AMD64) - ENABLE_LANGUAGE(ASM_MASM) - set(ZLIB_ASMS - contrib/masmx64/gvmat64.asm - contrib/masmx64/inffasx64.asm - ) - endif() - - if(ZLIB_ASMS) - add_definitions(-DASMV -DASMINF) - endif() -endif() - -# parse the full version number from zlib.h and include in ZLIB_FULL_VERSION -file(READ ${CMAKE_CURRENT_SOURCE_DIR}/zlib.h _zlib_h_contents) -string(REGEX REPLACE ".*#define[ \t]+ZLIB_VERSION[ \t]+\"([-0-9A-Za-z.]+)\".*" - "\\1" ZLIB_FULL_VERSION ${_zlib_h_contents}) - -if(MINGW) - # This gets us DLL resource information when compiling on MinGW. - if(NOT CMAKE_RC_COMPILER) - set(CMAKE_RC_COMPILER windres.exe) - endif() - - add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj - COMMAND ${CMAKE_RC_COMPILER} - -D GCC_WINDRES - -I ${CMAKE_CURRENT_SOURCE_DIR} - -I ${CMAKE_CURRENT_BINARY_DIR} - -o ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj - -i ${CMAKE_CURRENT_SOURCE_DIR}/win32/zlib1.rc) - set(ZLIB_DLL_SRCS ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj) -endif(MINGW) - -add_library(zlibstatic STATIC ${ZLIB_SRCS} ${ZLIB_ASMS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS}) -INSTALL( TARGETS zlibstatic - LIBRARY DESTINATION ${ASSIMP_LIB_INSTALL_DIR} - ARCHIVE DESTINATION ${ASSIMP_LIB_INSTALL_DIR} - RUNTIME DESTINATION ${ASSIMP_BIN_INSTALL_DIR} - COMPONENT ${LIBASSIMP_COMPONENT}) +cmake_minimum_required(VERSION 2.4.4) +set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON) + +# CMake 3.0 changed the project command, setting policy CMP0048 reverts to the old behaviour. +# See http://www.cmake.org/cmake/help/v3.0/policy/CMP0048.html +cmake_policy(PUSH) +if(CMAKE_MAJOR_VERSION GREATER 2) + cmake_policy(SET CMP0048 OLD) +endif() +project(zlib C) +cmake_policy(POP) + +set(VERSION "1.2.8") + +option(ASM686 "Enable building i686 assembly implementation for zlib") +option(AMD64 "Enable building amd64 assembly implementation for zlib") + +#set(INSTALL_BIN_DIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Installation directory for executables") +#set(INSTALL_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib" CACHE PATH "Installation directory for libraries") +#set(INSTALL_INC_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH "Installation directory for headers") +#set(INSTALL_MAN_DIR "${CMAKE_INSTALL_PREFIX}/share/man" CACHE PATH "Installation directory for manual pages") +#set(INSTALL_PKGCONFIG_DIR "${CMAKE_INSTALL_PREFIX}/share/pkgconfig" CACHE PATH "Installation directory for pkgconfig (.pc) files") + +include(CheckTypeSize) +include(CheckFunctionExists) +include(CheckIncludeFile) +include(CheckCSourceCompiles) +enable_testing() + +check_include_file(sys/types.h HAVE_SYS_TYPES_H) +check_include_file(stdint.h HAVE_STDINT_H) +check_include_file(stddef.h HAVE_STDDEF_H) + +# +# Check to see if we have large file support +# +set(CMAKE_REQUIRED_DEFINITIONS -D_LARGEFILE64_SOURCE=1) +# We add these other definitions here because CheckTypeSize.cmake +# in CMake 2.4.x does not automatically do so and we want +# compatibility with CMake 2.4.x. +if(HAVE_SYS_TYPES_H) + list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_SYS_TYPES_H) +endif() +if(HAVE_STDINT_H) + list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDINT_H) +endif() +if(HAVE_STDDEF_H) + list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDDEF_H) +endif() +check_type_size(off64_t OFF64_T) +if(HAVE_OFF64_T) + add_definitions(-D_LARGEFILE64_SOURCE=1) +endif() +set(CMAKE_REQUIRED_DEFINITIONS) # clear variable + +# +# Check for fseeko +# +check_function_exists(fseeko HAVE_FSEEKO) +if(NOT HAVE_FSEEKO) + add_definitions(-DNO_FSEEKO) +endif() + +# +# Check for unistd.h +# +check_include_file(unistd.h Z_HAVE_UNISTD_H) + +if(MSVC) + set(CMAKE_DEBUG_POSTFIX "d") + add_definitions(-D_CRT_SECURE_NO_DEPRECATE) + add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE) + include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +endif() + +if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR) + # If we're doing an out of source build and the user has a zconf.h + # in their source tree... + if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h) + message(STATUS "Renaming") + message(STATUS " ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h") + message(STATUS "to 'zconf.h.included' because this file is included with zlib") + message(STATUS "but CMake generates it automatically in the build directory.") + file(RENAME ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.included) + endif() +endif() + +set(ZLIB_PC ${CMAKE_CURRENT_BINARY_DIR}/zlib.pc) +configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/zlib.pc.cmakein + ${ZLIB_PC} @ONLY) +configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.cmakein + ${CMAKE_CURRENT_BINARY_DIR}/zconf.h @ONLY) + +include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}) + + +#============================================================================ +# zlib +#============================================================================ + +set(ZLIB_PUBLIC_HDRS + ${CMAKE_CURRENT_BINARY_DIR}/zconf.h + zlib.h +) +set(ZLIB_PRIVATE_HDRS + crc32.h + deflate.h + gzguts.h + inffast.h + inffixed.h + inflate.h + inftrees.h + trees.h + zutil.h +) +set(ZLIB_SRCS + adler32.c + compress.c + crc32.c + deflate.c + gzclose.c + gzlib.c + gzread.c + gzwrite.c + inflate.c + infback.c + inftrees.c + inffast.c + trees.c + uncompr.c + zutil.c +) + +if(NOT MINGW) + set(ZLIB_DLL_SRCS + win32/zlib1.rc # If present will override custom build rule below. + ) +endif() + +if(CMAKE_COMPILER_IS_GNUCC) + if(ASM686) + set(ZLIB_ASMS contrib/asm686/match.S) + elseif (AMD64) + set(ZLIB_ASMS contrib/amd64/amd64-match.S) + endif () + + if(ZLIB_ASMS) + add_definitions(-DASMV) + set_source_files_properties(${ZLIB_ASMS} PROPERTIES LANGUAGE C COMPILE_FLAGS -DNO_UNDERLINE) + endif() +endif() + +if(MSVC) + if(ASM686) + ENABLE_LANGUAGE(ASM_MASM) + set(ZLIB_ASMS + contrib/masmx86/inffas32.asm + contrib/masmx86/match686.asm + ) + elseif (AMD64) + ENABLE_LANGUAGE(ASM_MASM) + set(ZLIB_ASMS + contrib/masmx64/gvmat64.asm + contrib/masmx64/inffasx64.asm + ) + endif() + + if(ZLIB_ASMS) + add_definitions(-DASMV -DASMINF) + endif() +endif() + +# parse the full version number from zlib.h and include in ZLIB_FULL_VERSION +file(READ ${CMAKE_CURRENT_SOURCE_DIR}/zlib.h _zlib_h_contents) +string(REGEX REPLACE ".*#define[ \t]+ZLIB_VERSION[ \t]+\"([-0-9A-Za-z.]+)\".*" + "\\1" ZLIB_FULL_VERSION ${_zlib_h_contents}) + +if(MINGW) + # This gets us DLL resource information when compiling on MinGW. + if(NOT CMAKE_RC_COMPILER) + set(CMAKE_RC_COMPILER windres.exe) + endif() + + add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj + COMMAND ${CMAKE_RC_COMPILER} + -D GCC_WINDRES + -I ${CMAKE_CURRENT_SOURCE_DIR} + -I ${CMAKE_CURRENT_BINARY_DIR} + -o ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj + -i ${CMAKE_CURRENT_SOURCE_DIR}/win32/zlib1.rc) + set(ZLIB_DLL_SRCS ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj) +endif(MINGW) + +add_library(zlibstatic STATIC ${ZLIB_SRCS} ${ZLIB_ASMS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS}) +INSTALL( TARGETS zlibstatic + LIBRARY DESTINATION ${ASSIMP_LIB_INSTALL_DIR} + ARCHIVE DESTINATION ${ASSIMP_LIB_INSTALL_DIR} + RUNTIME DESTINATION ${ASSIMP_BIN_INSTALL_DIR} + COMPONENT ${LIBASSIMP_COMPONENT}) diff --git a/contrib/zlib_note.txt b/contrib/zlib_note.txt index 538f8011f..cc274f0bf 100644 --- a/contrib/zlib_note.txt +++ b/contrib/zlib_note.txt @@ -1,11 +1,11 @@ -This is a heavily modified and shrinked version of zlib 1.2.3 - -- Removed comments from zlib.h -- Removed gzip/zip archive I/O -- Removed infback.c -- Added Assimp #idefs to exclude it if not needed -- Disabled debug macros in zutil.h - -Assimp itself does not use the compression part yet, so -it needn't be compiled (trees.c, deflate.c, compress.c). +This is a heavily modified and shrinked version of zlib 1.2.3 + +- Removed comments from zlib.h +- Removed gzip/zip archive I/O +- Removed infback.c +- Added Assimp #idefs to exclude it if not needed +- Disabled debug macros in zutil.h + +Assimp itself does not use the compression part yet, so +it needn't be compiled (trees.c, deflate.c, compress.c). Currently these units are just used by assimp_cmd. \ No newline at end of file diff --git a/doc/Preamble.txt b/doc/Preamble.txt index 5b2fcaa73..0722a48e1 100644 --- a/doc/Preamble.txt +++ b/doc/Preamble.txt @@ -1,40 +1,40 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2012, assimp team - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- */ \ No newline at end of file diff --git a/doc/dox_cmd.h b/doc/dox_cmd.h index 8ebbcb360..bc2320e1e 100644 --- a/doc/dox_cmd.h +++ b/doc/dox_cmd.h @@ -1,548 +1,548 @@ -/** @file dox_cmd.h - * @brief General documentation for assimp_cmd - */ - - -//---------------------------------------------------------------------------------------------- -// ASSIMP CMD MAINPAGE -/** -@mainpage ASSIMP Command-line tools - - - -@section intro Introduction - -This document describes the usage of assimp's command line tools. -This is *not* the SDK reference and programming-related stuff is not covered here. -

-NOTE: For simplicity, the following sections are written with Windows in mind. However -it's not different for Linux/Mac at all, except there's probably no assimp.exe ... - -@section basic_use Basic use - -Open a command prompt and navigate to the directory where assimp.exe resides. The basic command line is: - -@code -assimp [command] [parameters] -@endcode - -The following commands are available: - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@link version version @endlinkRetrieve the current version of assimp
@link help help @endlinkGet a list of all commands (yes, it's this list ...)
@link dump dump @endlinkGenerate a human-readable text dump of a model
@link extract extract @endlinkExtract an embedded texture image
@link iinfo info @endlinkLoad a model and print basic statistics
@link cmpdump cmpdump @endlinkRegression checking tool
- -If you use assimp's command line frequently, consider adding assimp to your PATH -environment. - - */ - - -/** -@page version 'version'-Command - -Display the version/revision of Assimp used. - */ - -/** -@page help 'help'-Command - -Display a really helpful text. - */ - -//---------------------------------------------------------------------------------------------- -// ASSIMP INFO - -/** -@page iinfo 'info'-Command - -Load a model file and print basic statistics. Full postprocessing is applied unless the -r switch is specified. Sample output (assimp info ./test/models/3DS/mar_rifle.3ds): - -@verbatim -Launching model import ... OK -Validating postprocessing flags ... OK -Importing file ... OK - import took approx. 0.02400 seconds - -Memory consumption: 69444 B -Nodes: 2 -Maximum depth 2 -Meshes: 1 -Animations: 0 -Textures (embed.): 0 -Materials: 1 -Cameras: 0 -Lights: 0 -Vertices: 843 -Faces: 572 -Bones: 0 -Animation Channels: 0 -Primitive Types: triangles -Average faces/mesh 572 -Average verts/mesh 843 -Minimum point (-3.522588 -11.573204 -40.340359) -Maximum point (3.522622 30.196556 75.941292) -Center point (0.000017 9.311676 17.800467) - -Named Materials: - 'mat1' - -Texture Refs: - 'm_rifl.bmp' - -Node hierarchy: -'<3DSRoot>', meshes: 0 --- 'm_rifle', meshes: 1 -<-- -@endverbatim - -

Syntax:

- -@code -assimp info file [-r] -@endcode - - -

Parameters:

- -

- -file

-Required. Input file. -

-

- --r
-Optional. Don't perform any postprocessing. The long form of this parameter is --raw. -

- -*/ -//---------------------------------------------------------------------------------------------- -// ASSIMP CMPDUMP - -/** -@page cmpdump 'cmpdump'-Command - -Used for Assimp's internal regression testing. Compare two mini dumps (produced using assimp dump .. -b -s) and -report any differences. In the regression test suite, this facility is used to build a database of -'known-to-be-fine' mini dumps, which are regularly compared against current results to detect regressions. - -

Syntax:

- -@code -assimp cmpdmp actual expected -@endcode - - -

Parameters:

- -

- -actual

-Required. Mini dump now. -

-

- -expected

-Required. Archived dump from some point in the past. -

- -*/ - - -//---------------------------------------------------------------------------------------------- -// ASSIMP DUMP - -/** -@page dump 'dump'-Command - -Generate a text or binary dump of a model. This is the core component of Assimp's internal -regression test suite but it could also be useful for other developers to quickly -examine the contents of a model. Note that text dumps are not intended to be used as -intermediate format, Assimp is not able to read them again, nor is the file format -stable or well-defined. It may change with every revision without notice. -Binary dumps (*.assbin) are backwards- and forwards-compatible. - -

Syntax:

- -@code -assimp dump [] [-b] [-s] [common parameters] -@endcode - - -

Parameters:

- -

- -model

-Required. Relative or absolute path to the input model. -

-

- -out

-Optional. Relative or absolute path to write the output dump to. If it is omitted, -the dump is written to <model>-dump.txt -

- -

--b
-

-Optional. If this switch is specified, the dumb is written in binary format. -The long form of this parameter is --binary. -

- -

--s<n>
-

-Optional. If this switch is specified, the dumb is shortened to include only -min/max values for all vertex components and animation channels. The resulting -file is much smaller, but the original model can't be reconstructed from it. This is -used by Assimp's regression test suite, comparing those minidumps provides -a fast way to verify whether a loader works correctly or not. -The long form of this parameter is --short. -

- -

- -common parameters

-Optional. Import configuration & postprocessing. -See the @link common common parameters page @endlink for more information. -

- -
- -

Sample:

- -@code -assimp dump test.3ds test.txt -l -cfull -assimp dump test.3ds test.txt -include-log -config=full -@endcode - -Dumps 'test.3ds' to 'test.txt' after executing full post-processing on tehe imported data. -The log output is included with the dump. - - -@code -assimp dump files\*.* -assimp dump files\*.* -@endcode - -Dumps all loadable model files in the 'files' subdir. The output dumps are named --dump.txt. The log is not included. - */ - -//---------------------------------------------------------------------------------------------- -// ASSIMP EXTRACT - -/** -@page extract 'extract'-Command - -Extracts one or more embedded texture images from models. - -

Syntax:

- -@code -assimp extract [] [-t] [-f] [-ba] [-s] [common parameters] -@endcode - - -

Parameters:

- -

- -model

-Required. Relative or absolute path to the input model. -

-

- -out

-Optional. Relative or absolute path to write the output images to. If the file name is -omitted the output images are named
-The suffix _img<n> is appended to the file name if the -s switch is not specified -(where <n> is the zero-based index of the texture in the model file).
- -The output file format is determined from the given file extension. Supported -formats are BMP and TGA. If the file format can't be determined, -the value specified with the -f switch is taken. -
-Format settings are ignored for compressed embedded textures. They're always -written in their native file format (e.g. jpg). -

- -

--t<n>
-

-Optional. Specifies the (zero-based) index of the embedded texture to be extracted from -the model. If this option is *not* specified all textures found are exported. -The long form of this parameter is --texture=<n>. -

- -

--ba<n>
-

-Optional. Specifies whether output BMPs contain an alpha channel or not. -The long form of this parameter is --bmp-with-alpha=<n>. -

- - -

--f<n>
-

-Optional. Specifies the output file format. Supported -formats are BMP and TGA. The default value is BMP (if a full output filename is -specified, the output file format is taken from its extension, not from here). -The long form of this parameter is --format=<n>. -

- -

--s<n>
-

-Optional. Prevents the tool from adding the _img<n> suffix to all filenames. This option -must be specified together with -t to ensure that just one image is written. -The long form of this parameter is --nosuffix. -

- -

- -common parameters

-Optional. Import configuration & postprocessing. Most postprocessing-steps don't affect -embedded texture images, configuring too much is probably senseless here. -See the @link common common parameters page @endlink for more information. -

- -
- -

Sample:

- -@code -assimp extract test.mdl test.bmp --texture=0 --validate-data-structure -assimp extract test.mdl test.bmp -t=0 -vds -@endcode - -Extracts the first embedded texture (if any) from test.mdl after validating the -imported data structure and writes it to test_img0.bmp. - - -@code -assimp extract files\*.mdl *.bmp -assimp extract files\*.mdl *.bmp -@endcode - -Extracts all embedded textures from all loadable .mdl files in the 'files' subdirectory -and writes them to bitmaps which are named _img.bmp - */ - -//---------------------------------------------------------------------------------------------- -// ASSIMP COMMON PARAMETERS -/** -@page common Common parameters - -The parameters described on this page are commonly used by almost every assimp command. They -specify how the library will postprocess the imported data. This is done by several -configurable pipeline stages, called 'post processing steps'. Below you can find a list -of all supported steps along with short descriptions of what they're doing.
Programmers: -more information can be found in the aiPostProcess.h header. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ParameterLong parameterDescription
-ptv--pretransform-verticesMove all vertices into worldspace and collapse the scene graph. Animation data is lost. - This is intended for applications which don't support scenegraph-oriented rendering.
-gsn--gen-smooth-normalsComputes 'smooth' per-vertex normal vectors if necessary. Mutually exclusive with -gn
-gn--gen-normalsComputes 'hard' per-face normal vectors if necessary. Mutually exclusive with -gsn
-cts--calc-tangent-spaceIf one UV channel and normal vectors are given, compute tangents and bitangents
-jiv--join-identical-verticesOptimize the index buffer. If this flag is not specified all vertices are referenced once.
-rrm--remove-redundant-materialsRemove redundant materials from the imported data.
-fd--find-degeneratesFind and process degenerates primitives.
-slm--split-large-meshesSplit large meshes over a specific threshold in smaller sub meshes. The default vertex & face limit is 1000000
-lbw--limit-bone-weightsLimit the number of bones influencing a single vertex. The default limit is 4.
-vds--validate-data-structurePerforms a full validation of the imported data structure. Recommended to avoid crashes if - an import plugin produces rubbish
-icl--improve-cache-localityImprove the cache locality of the vertex buffer by reordering the index buffer - to achieve a lower ACMR (average post-transform vertex cache miss ratio)
-sbpt--sort-by-ptypeSplits meshes which consist of more than one kind of primitives (e.g. lines and triangles mixed up) - in 'clean' submeshes.
-lh--convert-to-lhConverts the imported data to left-handed coordinate space
-fuv--flip-uvFlip UV coordinates from upper-left origin to lower-left origin
-fwo--flip-winding-orderFlip face winding order from CCW to CW
-ett--evaluate-texture-transformEvaluate per-texture UV transformations (e.g scaling, offset) and build pretransformed UV channels
-guv--gen-uvcoordsReplace abstract mapping descriptions, such as 'spherical' or 'cylindrical' with proper UV channels
-fixn--fix-normalsRun a heuristic algorithm to detect meshes with wrong face winding order/normals.
-tri--triangulateTriangulate poylgons with 4 and more points. Lines, points and triangles are not affected.
-fi--find-instancesSearch the data structure for instanced meshes and replace them by references. This can - reduce vertex/face counts but the postprocessing-step takes some time.
-og--optimize-graphSimplify and optimize the scenegraph. Use it with care, all hierarchy information could be lost. - Animations remain untouched.
-om--optimize-meshOptimize mesh usage. Meshes are merged, if possible. Very effective in combination with --optimize-graph
- -For convenience some default postprocessing configurations are provided. -The corresponding command line parameter is -c<name> (or --config=<name>). - - - - - - - - - - - - - - - - - - - - - - - -
NameDescriptionList of steps executed
fastFast post processing config, performs some essential optimizations and computes tangents-cts, -gn, -jiv, -tri, -guv, -sbpt
defaultBalanced post processing config; performs most optimizations-cts, -gsn, -jiv, -icl, -lbw, -rrm, -slm, -tri, -guv, -sbpt, -fd, -fiv
fullFull post processing. May take a while but results in best output quality for most purposes-cts, -gsn, -jiv, -icl, -lbw, -rrm, -slm, -tri, -guv, -sbpt, -fd, -fiv, -fi, -vds -om
- - The -tuv, -ptv, -og flags always need to be enabled manually. - -There are also some common flags to customize Assimp's logging behaviour: - - - - - - - - - - - - - - - - - - - -
NameDescription
-l or --show-logShow log file on console window (stderr)
-lo<file> or --log-out=<file>Streams the log to <file>
-v or --verboseEnables verbose logging. Debug messages will be produced too. This might - decrease loading performance and result in *very* long logs ... use with caution if you experience strange issues.
- */ +/** @file dox_cmd.h + * @brief General documentation for assimp_cmd + */ + + +//---------------------------------------------------------------------------------------------- +// ASSIMP CMD MAINPAGE +/** +@mainpage ASSIMP Command-line tools + + + +@section intro Introduction + +This document describes the usage of assimp's command line tools. +This is *not* the SDK reference and programming-related stuff is not covered here. +

+NOTE: For simplicity, the following sections are written with Windows in mind. However +it's not different for Linux/Mac at all, except there's probably no assimp.exe ... + +@section basic_use Basic use + +Open a command prompt and navigate to the directory where assimp.exe resides. The basic command line is: + +@code +assimp [command] [parameters] +@endcode + +The following commands are available: + + + + + + + + + + + + + + + + + + + + + + + + + + + +
@link version version @endlinkRetrieve the current version of assimp
@link help help @endlinkGet a list of all commands (yes, it's this list ...)
@link dump dump @endlinkGenerate a human-readable text dump of a model
@link extract extract @endlinkExtract an embedded texture image
@link iinfo info @endlinkLoad a model and print basic statistics
@link cmpdump cmpdump @endlinkRegression checking tool
+ +If you use assimp's command line frequently, consider adding assimp to your PATH +environment. + + */ + + +/** +@page version 'version'-Command + +Display the version/revision of Assimp used. + */ + +/** +@page help 'help'-Command + +Display a really helpful text. + */ + +//---------------------------------------------------------------------------------------------- +// ASSIMP INFO + +/** +@page iinfo 'info'-Command + +Load a model file and print basic statistics. Full postprocessing is applied unless the -r switch is specified. Sample output (assimp info ./test/models/3DS/mar_rifle.3ds): + +@verbatim +Launching model import ... OK +Validating postprocessing flags ... OK +Importing file ... OK + import took approx. 0.02400 seconds + +Memory consumption: 69444 B +Nodes: 2 +Maximum depth 2 +Meshes: 1 +Animations: 0 +Textures (embed.): 0 +Materials: 1 +Cameras: 0 +Lights: 0 +Vertices: 843 +Faces: 572 +Bones: 0 +Animation Channels: 0 +Primitive Types: triangles +Average faces/mesh 572 +Average verts/mesh 843 +Minimum point (-3.522588 -11.573204 -40.340359) +Maximum point (3.522622 30.196556 75.941292) +Center point (0.000017 9.311676 17.800467) + +Named Materials: + 'mat1' + +Texture Refs: + 'm_rifl.bmp' + +Node hierarchy: +'<3DSRoot>', meshes: 0 +-- 'm_rifle', meshes: 1 +<-- +@endverbatim + +

Syntax:

+ +@code +assimp info file [-r] +@endcode + + +

Parameters:

+ +

+ +file

+Required. Input file. +

+

+ +-r
+Optional. Don't perform any postprocessing. The long form of this parameter is --raw. +

+ +*/ +//---------------------------------------------------------------------------------------------- +// ASSIMP CMPDUMP + +/** +@page cmpdump 'cmpdump'-Command + +Used for Assimp's internal regression testing. Compare two mini dumps (produced using assimp dump .. -b -s) and +report any differences. In the regression test suite, this facility is used to build a database of +'known-to-be-fine' mini dumps, which are regularly compared against current results to detect regressions. + +

Syntax:

+ +@code +assimp cmpdmp actual expected +@endcode + + +

Parameters:

+ +

+ +actual

+Required. Mini dump now. +

+

+ +expected

+Required. Archived dump from some point in the past. +

+ +*/ + + +//---------------------------------------------------------------------------------------------- +// ASSIMP DUMP + +/** +@page dump 'dump'-Command + +Generate a text or binary dump of a model. This is the core component of Assimp's internal +regression test suite but it could also be useful for other developers to quickly +examine the contents of a model. Note that text dumps are not intended to be used as +intermediate format, Assimp is not able to read them again, nor is the file format +stable or well-defined. It may change with every revision without notice. +Binary dumps (*.assbin) are backwards- and forwards-compatible. + +

Syntax:

+ +@code +assimp dump [] [-b] [-s] [common parameters] +@endcode + + +

Parameters:

+ +

+ +model

+Required. Relative or absolute path to the input model. +

+

+ +out

+Optional. Relative or absolute path to write the output dump to. If it is omitted, +the dump is written to <model>-dump.txt +

+ +

+-b
+

+Optional. If this switch is specified, the dumb is written in binary format. +The long form of this parameter is --binary. +

+ +

+-s<n>
+

+Optional. If this switch is specified, the dumb is shortened to include only +min/max values for all vertex components and animation channels. The resulting +file is much smaller, but the original model can't be reconstructed from it. This is +used by Assimp's regression test suite, comparing those minidumps provides +a fast way to verify whether a loader works correctly or not. +The long form of this parameter is --short. +

+ +

+ +common parameters

+Optional. Import configuration & postprocessing. +See the @link common common parameters page @endlink for more information. +

+ +
+ +

Sample:

+ +@code +assimp dump test.3ds test.txt -l -cfull +assimp dump test.3ds test.txt -include-log -config=full +@endcode + +Dumps 'test.3ds' to 'test.txt' after executing full post-processing on tehe imported data. +The log output is included with the dump. + + +@code +assimp dump files\*.* +assimp dump files\*.* +@endcode + +Dumps all loadable model files in the 'files' subdir. The output dumps are named +-dump.txt. The log is not included. + */ + +//---------------------------------------------------------------------------------------------- +// ASSIMP EXTRACT + +/** +@page extract 'extract'-Command + +Extracts one or more embedded texture images from models. + +

Syntax:

+ +@code +assimp extract [] [-t] [-f] [-ba] [-s] [common parameters] +@endcode + + +

Parameters:

+ +

+ +model

+Required. Relative or absolute path to the input model. +

+

+ +out

+Optional. Relative or absolute path to write the output images to. If the file name is +omitted the output images are named
+The suffix _img<n> is appended to the file name if the -s switch is not specified +(where <n> is the zero-based index of the texture in the model file).
+ +The output file format is determined from the given file extension. Supported +formats are BMP and TGA. If the file format can't be determined, +the value specified with the -f switch is taken. +
+Format settings are ignored for compressed embedded textures. They're always +written in their native file format (e.g. jpg). +

+ +

+-t<n>
+

+Optional. Specifies the (zero-based) index of the embedded texture to be extracted from +the model. If this option is *not* specified all textures found are exported. +The long form of this parameter is --texture=<n>. +

+ +

+-ba<n>
+

+Optional. Specifies whether output BMPs contain an alpha channel or not. +The long form of this parameter is --bmp-with-alpha=<n>. +

+ + +

+-f<n>
+

+Optional. Specifies the output file format. Supported +formats are BMP and TGA. The default value is BMP (if a full output filename is +specified, the output file format is taken from its extension, not from here). +The long form of this parameter is --format=<n>. +

+ +

+-s<n>
+

+Optional. Prevents the tool from adding the _img<n> suffix to all filenames. This option +must be specified together with -t to ensure that just one image is written. +The long form of this parameter is --nosuffix. +

+ +

+ +common parameters

+Optional. Import configuration & postprocessing. Most postprocessing-steps don't affect +embedded texture images, configuring too much is probably senseless here. +See the @link common common parameters page @endlink for more information. +

+ +
+ +

Sample:

+ +@code +assimp extract test.mdl test.bmp --texture=0 --validate-data-structure +assimp extract test.mdl test.bmp -t=0 -vds +@endcode + +Extracts the first embedded texture (if any) from test.mdl after validating the +imported data structure and writes it to test_img0.bmp. + + +@code +assimp extract files\*.mdl *.bmp +assimp extract files\*.mdl *.bmp +@endcode + +Extracts all embedded textures from all loadable .mdl files in the 'files' subdirectory +and writes them to bitmaps which are named _img.bmp + */ + +//---------------------------------------------------------------------------------------------- +// ASSIMP COMMON PARAMETERS +/** +@page common Common parameters + +The parameters described on this page are commonly used by almost every assimp command. They +specify how the library will postprocess the imported data. This is done by several +configurable pipeline stages, called 'post processing steps'. Below you can find a list +of all supported steps along with short descriptions of what they're doing.
Programmers: +more information can be found in the aiPostProcess.h header. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterLong parameterDescription
-ptv--pretransform-verticesMove all vertices into worldspace and collapse the scene graph. Animation data is lost. + This is intended for applications which don't support scenegraph-oriented rendering.
-gsn--gen-smooth-normalsComputes 'smooth' per-vertex normal vectors if necessary. Mutually exclusive with -gn
-gn--gen-normalsComputes 'hard' per-face normal vectors if necessary. Mutually exclusive with -gsn
-cts--calc-tangent-spaceIf one UV channel and normal vectors are given, compute tangents and bitangents
-jiv--join-identical-verticesOptimize the index buffer. If this flag is not specified all vertices are referenced once.
-rrm--remove-redundant-materialsRemove redundant materials from the imported data.
-fd--find-degeneratesFind and process degenerates primitives.
-slm--split-large-meshesSplit large meshes over a specific threshold in smaller sub meshes. The default vertex & face limit is 1000000
-lbw--limit-bone-weightsLimit the number of bones influencing a single vertex. The default limit is 4.
-vds--validate-data-structurePerforms a full validation of the imported data structure. Recommended to avoid crashes if + an import plugin produces rubbish
-icl--improve-cache-localityImprove the cache locality of the vertex buffer by reordering the index buffer + to achieve a lower ACMR (average post-transform vertex cache miss ratio)
-sbpt--sort-by-ptypeSplits meshes which consist of more than one kind of primitives (e.g. lines and triangles mixed up) + in 'clean' submeshes.
-lh--convert-to-lhConverts the imported data to left-handed coordinate space
-fuv--flip-uvFlip UV coordinates from upper-left origin to lower-left origin
-fwo--flip-winding-orderFlip face winding order from CCW to CW
-ett--evaluate-texture-transformEvaluate per-texture UV transformations (e.g scaling, offset) and build pretransformed UV channels
-guv--gen-uvcoordsReplace abstract mapping descriptions, such as 'spherical' or 'cylindrical' with proper UV channels
-fixn--fix-normalsRun a heuristic algorithm to detect meshes with wrong face winding order/normals.
-tri--triangulateTriangulate poylgons with 4 and more points. Lines, points and triangles are not affected.
-fi--find-instancesSearch the data structure for instanced meshes and replace them by references. This can + reduce vertex/face counts but the postprocessing-step takes some time.
-og--optimize-graphSimplify and optimize the scenegraph. Use it with care, all hierarchy information could be lost. + Animations remain untouched.
-om--optimize-meshOptimize mesh usage. Meshes are merged, if possible. Very effective in combination with --optimize-graph
+ +For convenience some default postprocessing configurations are provided. +The corresponding command line parameter is -c<name> (or --config=<name>). + + + + + + + + + + + + + + + + + + + + + + + +
NameDescriptionList of steps executed
fastFast post processing config, performs some essential optimizations and computes tangents-cts, -gn, -jiv, -tri, -guv, -sbpt
defaultBalanced post processing config; performs most optimizations-cts, -gsn, -jiv, -icl, -lbw, -rrm, -slm, -tri, -guv, -sbpt, -fd, -fiv
fullFull post processing. May take a while but results in best output quality for most purposes-cts, -gsn, -jiv, -icl, -lbw, -rrm, -slm, -tri, -guv, -sbpt, -fd, -fiv, -fi, -vds -om
+ + The -tuv, -ptv, -og flags always need to be enabled manually. + +There are also some common flags to customize Assimp's logging behaviour: + + + + + + + + + + + + + + + + + + + +
NameDescription
-l or --show-logShow log file on console window (stderr)
-lo<file> or --log-out=<file>Streams the log to <file>
-v or --verboseEnables verbose logging. Debug messages will be produced too. This might + decrease loading performance and result in *very* long logs ... use with caution if you experience strange issues.
+ */ diff --git a/include/assimp/Compiler/poppack1.h b/include/assimp/Compiler/poppack1.h index 531707420..e033bc147 100644 --- a/include/assimp/Compiler/poppack1.h +++ b/include/assimp/Compiler/poppack1.h @@ -1,22 +1,22 @@ - -// =============================================================================== -// May be included multiple times - resets structure packing to the defaults -// for all supported compilers. Reverts the changes made by #include -// -// Currently this works on the following compilers: -// MSVC 7,8,9 -// GCC -// BORLAND (complains about 'pack state changed but not reverted', but works) -// =============================================================================== - -#ifndef AI_PUSHPACK_IS_DEFINED -# error pushpack1.h must be included after poppack1.h -#endif - -// reset packing to the original value -#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) -# pragma pack( pop ) -#endif -#undef PACK_STRUCT - -#undef AI_PUSHPACK_IS_DEFINED + +// =============================================================================== +// May be included multiple times - resets structure packing to the defaults +// for all supported compilers. Reverts the changes made by #include +// +// Currently this works on the following compilers: +// MSVC 7,8,9 +// GCC +// BORLAND (complains about 'pack state changed but not reverted', but works) +// =============================================================================== + +#ifndef AI_PUSHPACK_IS_DEFINED +# error pushpack1.h must be included after poppack1.h +#endif + +// reset packing to the original value +#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) +# pragma pack( pop ) +#endif +#undef PACK_STRUCT + +#undef AI_PUSHPACK_IS_DEFINED diff --git a/include/assimp/Compiler/pstdint.h b/include/assimp/Compiler/pstdint.h index 7d0e2bc58..5bc322fab 100644 --- a/include/assimp/Compiler/pstdint.h +++ b/include/assimp/Compiler/pstdint.h @@ -1,729 +1,729 @@ -/* A portable stdint.h - **************************************************************************** - * BSD License: - **************************************************************************** - * - * Copyright (c) 2005-2007 Paul Hsieh - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - **************************************************************************** - * - * Version 0.1.10 - * - * The ANSI C standard committee, for the C99 standard, specified the - * inclusion of a new standard include file called stdint.h. This is - * a very useful and long desired include file which contains several - * very precise definitions for integer scalar types that is - * critically important for making portable several classes of - * applications including cryptography, hashing, variable length - * integer libraries and so on. But for most developers its likely - * useful just for programming sanity. - * - * The problem is that most compiler vendors have decided not to - * implement the C99 standard, and the next C++ language standard - * (which has a lot more mindshare these days) will be a long time in - * coming and its unknown whether or not it will include stdint.h or - * how much adoption it will have. Either way, it will be a long time - * before all compilers come with a stdint.h and it also does nothing - * for the extremely large number of compilers available today which - * do not include this file, or anything comparable to it. - * - * So that's what this file is all about. Its an attempt to build a - * single universal include file that works on as many platforms as - * possible to deliver what stdint.h is supposed to. A few things - * that should be noted about this file: - * - * 1) It is not guaranteed to be portable and/or present an identical - * interface on all platforms. The extreme variability of the - * ANSI C standard makes this an impossibility right from the - * very get go. Its really only meant to be useful for the vast - * majority of platforms that possess the capability of - * implementing usefully and precisely defined, standard sized - * integer scalars. Systems which are not intrinsically 2s - * complement may produce invalid constants. - * - * 2) There is an unavoidable use of non-reserved symbols. - * - * 3) Other standard include files are invoked. - * - * 4) This file may come in conflict with future platforms that do - * include stdint.h. The hope is that one or the other can be - * used with no real difference. - * - * 5) In the current verison, if your platform can't represent - * int32_t, int16_t and int8_t, it just dumps out with a compiler - * error. - * - * 6) 64 bit integers may or may not be defined. Test for their - * presence with the test: #ifdef INT64_MAX or #ifdef UINT64_MAX. - * Note that this is different from the C99 specification which - * requires the existence of 64 bit support in the compiler. If - * this is not defined for your platform, yet it is capable of - * dealing with 64 bits then it is because this file has not yet - * been extended to cover all of your system's capabilities. - * - * 7) (u)intptr_t may or may not be defined. Test for its presence - * with the test: #ifdef PTRDIFF_MAX. If this is not defined - * for your platform, then it is because this file has not yet - * been extended to cover all of your system's capabilities, not - * because its optional. - * - * 8) The following might not been defined even if your platform is - * capable of defining it: - * - * WCHAR_MIN - * WCHAR_MAX - * (u)int64_t - * PTRDIFF_MIN - * PTRDIFF_MAX - * (u)intptr_t - * - * 9) The following have not been defined: - * - * WINT_MIN - * WINT_MAX - * - * 10) The criteria for defining (u)int_least(*)_t isn't clear, - * except for systems which don't have a type that precisely - * defined 8, 16, or 32 bit types (which this include file does - * not support anyways). Default definitions have been given. - * - * 11) The criteria for defining (u)int_fast(*)_t isn't something I - * would trust to any particular compiler vendor or the ANSI C - * committee. It is well known that "compatible systems" are - * commonly created that have very different performance - * characteristics from the systems they are compatible with, - * especially those whose vendors make both the compiler and the - * system. Default definitions have been given, but its strongly - * recommended that users never use these definitions for any - * reason (they do *NOT* deliver any serious guarantee of - * improved performance -- not in this file, nor any vendor's - * stdint.h). - * - * 12) The following macros: - * - * PRINTF_INTMAX_MODIFIER - * PRINTF_INT64_MODIFIER - * PRINTF_INT32_MODIFIER - * PRINTF_INT16_MODIFIER - * PRINTF_LEAST64_MODIFIER - * PRINTF_LEAST32_MODIFIER - * PRINTF_LEAST16_MODIFIER - * PRINTF_INTPTR_MODIFIER - * - * are strings which have been defined as the modifiers required - * for the "d", "u" and "x" printf formats to correctly output - * (u)intmax_t, (u)int64_t, (u)int32_t, (u)int16_t, (u)least64_t, - * (u)least32_t, (u)least16_t and (u)intptr_t types respectively. - * PRINTF_INTPTR_MODIFIER is not defined for some systems which - * provide their own stdint.h. PRINTF_INT64_MODIFIER is not - * defined if INT64_MAX is not defined. These are an extension - * beyond what C99 specifies must be in stdint.h. - * - * In addition, the following macros are defined: - * - * PRINTF_INTMAX_HEX_WIDTH - * PRINTF_INT64_HEX_WIDTH - * PRINTF_INT32_HEX_WIDTH - * PRINTF_INT16_HEX_WIDTH - * PRINTF_INT8_HEX_WIDTH - * PRINTF_INTMAX_DEC_WIDTH - * PRINTF_INT64_DEC_WIDTH - * PRINTF_INT32_DEC_WIDTH - * PRINTF_INT16_DEC_WIDTH - * PRINTF_INT8_DEC_WIDTH - * - * Which specifies the maximum number of characters required to - * print the number of that type in either hexadecimal or decimal. - * These are an extension beyond what C99 specifies must be in - * stdint.h. - * - * Compilers tested (all with 0 warnings at their highest respective - * settings): Borland Turbo C 2.0, WATCOM C/C++ 11.0 (16 bits and 32 - * bits), Microsoft Visual C++ 6.0 (32 bit), Microsoft Visual Studio - * .net (VC7), Intel C++ 4.0, GNU gcc v3.3.3 - * - * This file should be considered a work in progress. Suggestions for - * improvements, especially those which increase coverage are strongly - * encouraged. - * - * Acknowledgements - * - * The following people have made significant contributions to the - * development and testing of this file: - * - * Chris Howie - * John Steele Scott - * Dave Thorup - * - */ - -#include -#include -#include - -/* - * For gcc with _STDINT_H, fill in the PRINTF_INT*_MODIFIER macros, and - * do nothing else. On the Mac OS X version of gcc this is _STDINT_H_. - */ - -#if ((defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined (__WATCOMC__) && (defined (_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_)))) && !defined (_PSTDINT_H_INCLUDED) && !defined(_STDINT) -#include -#define _PSTDINT_H_INCLUDED -# ifndef PRINTF_INT64_MODIFIER -# define PRINTF_INT64_MODIFIER "ll" -# endif -# ifndef PRINTF_INT32_MODIFIER -# define PRINTF_INT32_MODIFIER "l" -# endif -# ifndef PRINTF_INT16_MODIFIER -# define PRINTF_INT16_MODIFIER "h" -# endif -# ifndef PRINTF_INTMAX_MODIFIER -# define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER -# endif -# ifndef PRINTF_INT64_HEX_WIDTH -# define PRINTF_INT64_HEX_WIDTH "16" -# endif -# ifndef PRINTF_INT32_HEX_WIDTH -# define PRINTF_INT32_HEX_WIDTH "8" -# endif -# ifndef PRINTF_INT16_HEX_WIDTH -# define PRINTF_INT16_HEX_WIDTH "4" -# endif -# ifndef PRINTF_INT8_HEX_WIDTH -# define PRINTF_INT8_HEX_WIDTH "2" -# endif -# ifndef PRINTF_INT64_DEC_WIDTH -# define PRINTF_INT64_DEC_WIDTH "20" -# endif -# ifndef PRINTF_INT32_DEC_WIDTH -# define PRINTF_INT32_DEC_WIDTH "10" -# endif -# ifndef PRINTF_INT16_DEC_WIDTH -# define PRINTF_INT16_DEC_WIDTH "5" -# endif -# ifndef PRINTF_INT8_DEC_WIDTH -# define PRINTF_INT8_DEC_WIDTH "3" -# endif -# ifndef PRINTF_INTMAX_HEX_WIDTH -# define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT64_HEX_WIDTH -# endif -# ifndef PRINTF_INTMAX_DEC_WIDTH -# define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT64_DEC_WIDTH -# endif - -/* - * Something really weird is going on with Open Watcom. Just pull some of - * these duplicated definitions from Open Watcom's stdint.h file for now. - */ - -# if defined (__WATCOMC__) && __WATCOMC__ >= 1250 -# if !defined (INT64_C) -# define INT64_C(x) (x + (INT64_MAX - INT64_MAX)) -# endif -# if !defined (UINT64_C) -# define UINT64_C(x) (x + (UINT64_MAX - UINT64_MAX)) -# endif -# if !defined (INT32_C) -# define INT32_C(x) (x + (INT32_MAX - INT32_MAX)) -# endif -# if !defined (UINT32_C) -# define UINT32_C(x) (x + (UINT32_MAX - UINT32_MAX)) -# endif -# if !defined (INT16_C) -# define INT16_C(x) (x) -# endif -# if !defined (UINT16_C) -# define UINT16_C(x) (x) -# endif -# if !defined (INT8_C) -# define INT8_C(x) (x) -# endif -# if !defined (UINT8_C) -# define UINT8_C(x) (x) -# endif -# if !defined (UINT64_MAX) -# define UINT64_MAX 18446744073709551615ULL -# endif -# if !defined (INT64_MAX) -# define INT64_MAX 9223372036854775807LL -# endif -# if !defined (UINT32_MAX) -# define UINT32_MAX 4294967295UL -# endif -# if !defined (INT32_MAX) -# define INT32_MAX 2147483647L -# endif -# if !defined (INTMAX_MAX) -# define INTMAX_MAX INT64_MAX -# endif -# if !defined (INTMAX_MIN) -# define INTMAX_MIN INT64_MIN -# endif -# endif -#endif - -#ifndef _PSTDINT_H_INCLUDED -#define _PSTDINT_H_INCLUDED - -#ifndef SIZE_MAX -# define SIZE_MAX (~(size_t)0) -#endif - -/* - * Deduce the type assignments from limits.h under the assumption that - * integer sizes in bits are powers of 2, and follow the ANSI - * definitions. - */ - -#ifndef UINT8_MAX -# define UINT8_MAX 0xff -#endif -#ifndef uint8_t -# if (UCHAR_MAX == UINT8_MAX) || defined (S_SPLINT_S) - typedef unsigned char uint8_t; -# define UINT8_C(v) ((uint8_t) v) -# else -# error "Platform not supported" -# endif -#endif - -#ifndef INT8_MAX -# define INT8_MAX 0x7f -#endif -#ifndef INT8_MIN -# define INT8_MIN INT8_C(0x80) -#endif -#ifndef int8_t -# if (SCHAR_MAX == INT8_MAX) || defined (S_SPLINT_S) - typedef signed char int8_t; -# define INT8_C(v) ((int8_t) v) -# else -# error "Platform not supported" -# endif -#endif - -#ifndef UINT16_MAX -# define UINT16_MAX 0xffff -#endif -#ifndef uint16_t -#if (UINT_MAX == UINT16_MAX) || defined (S_SPLINT_S) - typedef unsigned int uint16_t; -# ifndef PRINTF_INT16_MODIFIER -# define PRINTF_INT16_MODIFIER "" -# endif -# define UINT16_C(v) ((uint16_t) (v)) -#elif (USHRT_MAX == UINT16_MAX) - typedef unsigned short uint16_t; -# define UINT16_C(v) ((uint16_t) (v)) -# ifndef PRINTF_INT16_MODIFIER -# define PRINTF_INT16_MODIFIER "h" -# endif -#else -#error "Platform not supported" -#endif -#endif - -#ifndef INT16_MAX -# define INT16_MAX 0x7fff -#endif -#ifndef INT16_MIN -# define INT16_MIN INT16_C(0x8000) -#endif -#ifndef int16_t -#if (INT_MAX == INT16_MAX) || defined (S_SPLINT_S) - typedef signed int int16_t; -# define INT16_C(v) ((int16_t) (v)) -# ifndef PRINTF_INT16_MODIFIER -# define PRINTF_INT16_MODIFIER "" -# endif -#elif (SHRT_MAX == INT16_MAX) - typedef signed short int16_t; -# define INT16_C(v) ((int16_t) (v)) -# ifndef PRINTF_INT16_MODIFIER -# define PRINTF_INT16_MODIFIER "h" -# endif -#else -#error "Platform not supported" -#endif -#endif - -#ifndef UINT32_MAX -# define UINT32_MAX (0xffffffffUL) -#endif -#ifndef uint32_t -#if (ULONG_MAX == UINT32_MAX) || defined (S_SPLINT_S) - typedef unsigned long uint32_t; -# define UINT32_C(v) v ## UL -# ifndef PRINTF_INT32_MODIFIER -# define PRINTF_INT32_MODIFIER "l" -# endif -#elif (UINT_MAX == UINT32_MAX) - typedef unsigned int uint32_t; -# ifndef PRINTF_INT32_MODIFIER -# define PRINTF_INT32_MODIFIER "" -# endif -# define UINT32_C(v) v ## U -#elif (USHRT_MAX == UINT32_MAX) - typedef unsigned short uint32_t; -# define UINT32_C(v) ((unsigned short) (v)) -# ifndef PRINTF_INT32_MODIFIER -# define PRINTF_INT32_MODIFIER "" -# endif -#else -#error "Platform not supported" -#endif -#endif - -#ifndef INT32_MAX -# define INT32_MAX (0x7fffffffL) -#endif -#ifndef INT32_MIN -# define INT32_MIN INT32_C(0x80000000) -#endif -#ifndef int32_t -#if (LONG_MAX == INT32_MAX) || defined (S_SPLINT_S) - typedef signed long int32_t; -# define INT32_C(v) v ## L -# ifndef PRINTF_INT32_MODIFIER -# define PRINTF_INT32_MODIFIER "l" -# endif -#elif (INT_MAX == INT32_MAX) - typedef signed int int32_t; -# define INT32_C(v) v -# ifndef PRINTF_INT32_MODIFIER -# define PRINTF_INT32_MODIFIER "" -# endif -#elif (SHRT_MAX == INT32_MAX) - typedef signed short int32_t; -# define INT32_C(v) ((short) (v)) -# ifndef PRINTF_INT32_MODIFIER -# define PRINTF_INT32_MODIFIER "" -# endif -#else -#error "Platform not supported" -#endif -#endif - -/* - * The macro stdint_int64_defined is temporarily used to record - * whether or not 64 integer support is available. It must be - * defined for any 64 integer extensions for new platforms that are - * added. - */ - -#undef stdint_int64_defined -#if (defined(__STDC__) && defined(__STDC_VERSION__)) || defined (S_SPLINT_S) -# if (__STDC__ && __STDC_VERSION >= 199901L) || defined (S_SPLINT_S) -# define stdint_int64_defined - typedef long long int64_t; - typedef unsigned long long uint64_t; -# define UINT64_C(v) v ## ULL -# define INT64_C(v) v ## LL -# ifndef PRINTF_INT64_MODIFIER -# define PRINTF_INT64_MODIFIER "ll" -# endif -# endif -#endif - -#if !defined (stdint_int64_defined) -# if defined(__GNUC__) -# define stdint_int64_defined - __extension__ typedef long long int64_t; - __extension__ typedef unsigned long long uint64_t; -# define UINT64_C(v) v ## ULL -# define INT64_C(v) v ## LL -# ifndef PRINTF_INT64_MODIFIER -# define PRINTF_INT64_MODIFIER "ll" -# endif -# elif defined(__MWERKS__) || defined (__SUNPRO_C) || defined (__SUNPRO_CC) || defined (__APPLE_CC__) || defined (_LONG_LONG) || defined (_CRAYC) || defined (S_SPLINT_S) -# define stdint_int64_defined - typedef long long int64_t; - typedef unsigned long long uint64_t; -# define UINT64_C(v) v ## ULL -# define INT64_C(v) v ## LL -# ifndef PRINTF_INT64_MODIFIER -# define PRINTF_INT64_MODIFIER "ll" -# endif -# elif (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) || (defined(_MSC_VER) && _INTEGRAL_MAX_BITS >= 64) || (defined (__BORLANDC__) && __BORLANDC__ > 0x460) || defined (__alpha) || defined (__DECC) -# define stdint_int64_defined - typedef __int64 int64_t; - typedef unsigned __int64 uint64_t; -# define UINT64_C(v) v ## UI64 -# define INT64_C(v) v ## I64 -# ifndef PRINTF_INT64_MODIFIER -# define PRINTF_INT64_MODIFIER "I64" -# endif -# endif -#endif - -#if !defined (LONG_LONG_MAX) && defined (INT64_C) -# define LONG_LONG_MAX INT64_C (9223372036854775807) -#endif -#ifndef ULONG_LONG_MAX -# define ULONG_LONG_MAX UINT64_C (18446744073709551615) -#endif - -#if !defined (INT64_MAX) && defined (INT64_C) -# define INT64_MAX INT64_C (9223372036854775807) -#endif -#if !defined (INT64_MIN) && defined (INT64_C) -# define INT64_MIN INT64_C (-9223372036854775808) -#endif -#if !defined (UINT64_MAX) && defined (INT64_C) -# define UINT64_MAX UINT64_C (18446744073709551615) -#endif - -/* - * Width of hexadecimal for number field. - */ - -#ifndef PRINTF_INT64_HEX_WIDTH -# define PRINTF_INT64_HEX_WIDTH "16" -#endif -#ifndef PRINTF_INT32_HEX_WIDTH -# define PRINTF_INT32_HEX_WIDTH "8" -#endif -#ifndef PRINTF_INT16_HEX_WIDTH -# define PRINTF_INT16_HEX_WIDTH "4" -#endif -#ifndef PRINTF_INT8_HEX_WIDTH -# define PRINTF_INT8_HEX_WIDTH "2" -#endif - -#ifndef PRINTF_INT64_DEC_WIDTH -# define PRINTF_INT64_DEC_WIDTH "20" -#endif -#ifndef PRINTF_INT32_DEC_WIDTH -# define PRINTF_INT32_DEC_WIDTH "10" -#endif -#ifndef PRINTF_INT16_DEC_WIDTH -# define PRINTF_INT16_DEC_WIDTH "5" -#endif -#ifndef PRINTF_INT8_DEC_WIDTH -# define PRINTF_INT8_DEC_WIDTH "3" -#endif - -/* - * Ok, lets not worry about 128 bit integers for now. Moore's law says - * we don't need to worry about that until about 2040 at which point - * we'll have bigger things to worry about. - */ - -#ifdef stdint_int64_defined - typedef int64_t intmax_t; - typedef uint64_t uintmax_t; -# define INTMAX_MAX INT64_MAX -# define INTMAX_MIN INT64_MIN -# define UINTMAX_MAX UINT64_MAX -# define UINTMAX_C(v) UINT64_C(v) -# define INTMAX_C(v) INT64_C(v) -# ifndef PRINTF_INTMAX_MODIFIER -# define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER -# endif -# ifndef PRINTF_INTMAX_HEX_WIDTH -# define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT64_HEX_WIDTH -# endif -# ifndef PRINTF_INTMAX_DEC_WIDTH -# define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT64_DEC_WIDTH -# endif -#else - typedef int32_t intmax_t; - typedef uint32_t uintmax_t; -# define INTMAX_MAX INT32_MAX -# define UINTMAX_MAX UINT32_MAX -# define UINTMAX_C(v) UINT32_C(v) -# define INTMAX_C(v) INT32_C(v) -# ifndef PRINTF_INTMAX_MODIFIER -# define PRINTF_INTMAX_MODIFIER PRINTF_INT32_MODIFIER -# endif -# ifndef PRINTF_INTMAX_HEX_WIDTH -# define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT32_HEX_WIDTH -# endif -# ifndef PRINTF_INTMAX_DEC_WIDTH -# define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT32_DEC_WIDTH -# endif -#endif - -/* - * Because this file currently only supports platforms which have - * precise powers of 2 as bit sizes for the default integers, the - * least definitions are all trivial. Its possible that a future - * version of this file could have different definitions. - */ - -#ifndef stdint_least_defined - typedef int8_t int_least8_t; - typedef uint8_t uint_least8_t; - typedef int16_t int_least16_t; - typedef uint16_t uint_least16_t; - typedef int32_t int_least32_t; - typedef uint32_t uint_least32_t; -# define PRINTF_LEAST32_MODIFIER PRINTF_INT32_MODIFIER -# define PRINTF_LEAST16_MODIFIER PRINTF_INT16_MODIFIER -# define UINT_LEAST8_MAX UINT8_MAX -# define INT_LEAST8_MAX INT8_MAX -# define UINT_LEAST16_MAX UINT16_MAX -# define INT_LEAST16_MAX INT16_MAX -# define UINT_LEAST32_MAX UINT32_MAX -# define INT_LEAST32_MAX INT32_MAX -# define INT_LEAST8_MIN INT8_MIN -# define INT_LEAST16_MIN INT16_MIN -# define INT_LEAST32_MIN INT32_MIN -# ifdef stdint_int64_defined - typedef int64_t int_least64_t; - typedef uint64_t uint_least64_t; -# define PRINTF_LEAST64_MODIFIER PRINTF_INT64_MODIFIER -# define UINT_LEAST64_MAX UINT64_MAX -# define INT_LEAST64_MAX INT64_MAX -# define INT_LEAST64_MIN INT64_MIN -# endif -#endif -#undef stdint_least_defined - -/* - * The ANSI C committee pretending to know or specify anything about - * performance is the epitome of misguided arrogance. The mandate of - * this file is to *ONLY* ever support that absolute minimum - * definition of the fast integer types, for compatibility purposes. - * No extensions, and no attempt to suggest what may or may not be a - * faster integer type will ever be made in this file. Developers are - * warned to stay away from these types when using this or any other - * stdint.h. - */ - -typedef int_least8_t int_fast8_t; -typedef uint_least8_t uint_fast8_t; -typedef int_least16_t int_fast16_t; -typedef uint_least16_t uint_fast16_t; -typedef int_least32_t int_fast32_t; -typedef uint_least32_t uint_fast32_t; -#define UINT_FAST8_MAX UINT_LEAST8_MAX -#define INT_FAST8_MAX INT_LEAST8_MAX -#define UINT_FAST16_MAX UINT_LEAST16_MAX -#define INT_FAST16_MAX INT_LEAST16_MAX -#define UINT_FAST32_MAX UINT_LEAST32_MAX -#define INT_FAST32_MAX INT_LEAST32_MAX -#define INT_FAST8_MIN INT_LEAST8_MIN -#define INT_FAST16_MIN INT_LEAST16_MIN -#define INT_FAST32_MIN INT_LEAST32_MIN -#ifdef stdint_int64_defined - typedef int_least64_t int_fast64_t; - typedef uint_least64_t uint_fast64_t; -# define UINT_FAST64_MAX UINT_LEAST64_MAX -# define INT_FAST64_MAX INT_LEAST64_MAX -# define INT_FAST64_MIN INT_LEAST64_MIN -#endif - -#undef stdint_int64_defined - -/* - * Whatever piecemeal, per compiler thing we can do about the wchar_t - * type limits. - */ - -#if defined(__WATCOMC__) || defined(_MSC_VER) || defined (__GNUC__) -# include -# ifndef WCHAR_MIN -# define WCHAR_MIN 0 -# endif -# ifndef WCHAR_MAX -# define WCHAR_MAX ((wchar_t)-1) -# endif -#endif - -/* - * Whatever piecemeal, per compiler/platform thing we can do about the - * (u)intptr_t types and limits. - */ - -#if defined (_MSC_VER) && defined (_UINTPTR_T_DEFINED) -# define STDINT_H_UINTPTR_T_DEFINED -#endif - -#ifndef STDINT_H_UINTPTR_T_DEFINED -# if defined (__alpha__) || defined (__ia64__) || defined (__x86_64__) || defined (_WIN64) -# define stdint_intptr_bits 64 -# elif defined (__WATCOMC__) || defined (__TURBOC__) -# if defined(__TINY__) || defined(__SMALL__) || defined(__MEDIUM__) -# define stdint_intptr_bits 16 -# else -# define stdint_intptr_bits 32 -# endif -# elif defined (__i386__) || defined (_WIN32) || defined (WIN32) -# define stdint_intptr_bits 32 -# elif defined (__INTEL_COMPILER) -/* TODO -- what will Intel do about x86-64? */ -# endif - -# ifdef stdint_intptr_bits -# define stdint_intptr_glue3_i(a,b,c) a##b##c -# define stdint_intptr_glue3(a,b,c) stdint_intptr_glue3_i(a,b,c) -# ifndef PRINTF_INTPTR_MODIFIER -# define PRINTF_INTPTR_MODIFIER stdint_intptr_glue3(PRINTF_INT,stdint_intptr_bits,_MODIFIER) -# endif -# ifndef PTRDIFF_MAX -# define PTRDIFF_MAX stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX) -# endif -# ifndef PTRDIFF_MIN -# define PTRDIFF_MIN stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN) -# endif -# ifndef UINTPTR_MAX -# define UINTPTR_MAX stdint_intptr_glue3(UINT,stdint_intptr_bits,_MAX) -# endif -# ifndef INTPTR_MAX -# define INTPTR_MAX stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX) -# endif -# ifndef INTPTR_MIN -# define INTPTR_MIN stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN) -# endif -# ifndef INTPTR_C -# define INTPTR_C(x) stdint_intptr_glue3(INT,stdint_intptr_bits,_C)(x) -# endif -# ifndef UINTPTR_C -# define UINTPTR_C(x) stdint_intptr_glue3(UINT,stdint_intptr_bits,_C)(x) -# endif - typedef stdint_intptr_glue3(uint,stdint_intptr_bits,_t) uintptr_t; - typedef stdint_intptr_glue3( int,stdint_intptr_bits,_t) intptr_t; -# else -/* TODO -- This following is likely wrong for some platforms, and does - nothing for the definition of uintptr_t. */ - typedef ptrdiff_t intptr_t; -# endif -# define STDINT_H_UINTPTR_T_DEFINED -#endif - -/* - * Assumes sig_atomic_t is signed and we have a 2s complement machine. - */ - -#ifndef SIG_ATOMIC_MAX -# define SIG_ATOMIC_MAX ((((sig_atomic_t) 1) << (sizeof (sig_atomic_t)*CHAR_BIT-1)) - 1) -#endif - -#endif - +/* A portable stdint.h + **************************************************************************** + * BSD License: + **************************************************************************** + * + * Copyright (c) 2005-2007 Paul Hsieh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************** + * + * Version 0.1.10 + * + * The ANSI C standard committee, for the C99 standard, specified the + * inclusion of a new standard include file called stdint.h. This is + * a very useful and long desired include file which contains several + * very precise definitions for integer scalar types that is + * critically important for making portable several classes of + * applications including cryptography, hashing, variable length + * integer libraries and so on. But for most developers its likely + * useful just for programming sanity. + * + * The problem is that most compiler vendors have decided not to + * implement the C99 standard, and the next C++ language standard + * (which has a lot more mindshare these days) will be a long time in + * coming and its unknown whether or not it will include stdint.h or + * how much adoption it will have. Either way, it will be a long time + * before all compilers come with a stdint.h and it also does nothing + * for the extremely large number of compilers available today which + * do not include this file, or anything comparable to it. + * + * So that's what this file is all about. Its an attempt to build a + * single universal include file that works on as many platforms as + * possible to deliver what stdint.h is supposed to. A few things + * that should be noted about this file: + * + * 1) It is not guaranteed to be portable and/or present an identical + * interface on all platforms. The extreme variability of the + * ANSI C standard makes this an impossibility right from the + * very get go. Its really only meant to be useful for the vast + * majority of platforms that possess the capability of + * implementing usefully and precisely defined, standard sized + * integer scalars. Systems which are not intrinsically 2s + * complement may produce invalid constants. + * + * 2) There is an unavoidable use of non-reserved symbols. + * + * 3) Other standard include files are invoked. + * + * 4) This file may come in conflict with future platforms that do + * include stdint.h. The hope is that one or the other can be + * used with no real difference. + * + * 5) In the current verison, if your platform can't represent + * int32_t, int16_t and int8_t, it just dumps out with a compiler + * error. + * + * 6) 64 bit integers may or may not be defined. Test for their + * presence with the test: #ifdef INT64_MAX or #ifdef UINT64_MAX. + * Note that this is different from the C99 specification which + * requires the existence of 64 bit support in the compiler. If + * this is not defined for your platform, yet it is capable of + * dealing with 64 bits then it is because this file has not yet + * been extended to cover all of your system's capabilities. + * + * 7) (u)intptr_t may or may not be defined. Test for its presence + * with the test: #ifdef PTRDIFF_MAX. If this is not defined + * for your platform, then it is because this file has not yet + * been extended to cover all of your system's capabilities, not + * because its optional. + * + * 8) The following might not been defined even if your platform is + * capable of defining it: + * + * WCHAR_MIN + * WCHAR_MAX + * (u)int64_t + * PTRDIFF_MIN + * PTRDIFF_MAX + * (u)intptr_t + * + * 9) The following have not been defined: + * + * WINT_MIN + * WINT_MAX + * + * 10) The criteria for defining (u)int_least(*)_t isn't clear, + * except for systems which don't have a type that precisely + * defined 8, 16, or 32 bit types (which this include file does + * not support anyways). Default definitions have been given. + * + * 11) The criteria for defining (u)int_fast(*)_t isn't something I + * would trust to any particular compiler vendor or the ANSI C + * committee. It is well known that "compatible systems" are + * commonly created that have very different performance + * characteristics from the systems they are compatible with, + * especially those whose vendors make both the compiler and the + * system. Default definitions have been given, but its strongly + * recommended that users never use these definitions for any + * reason (they do *NOT* deliver any serious guarantee of + * improved performance -- not in this file, nor any vendor's + * stdint.h). + * + * 12) The following macros: + * + * PRINTF_INTMAX_MODIFIER + * PRINTF_INT64_MODIFIER + * PRINTF_INT32_MODIFIER + * PRINTF_INT16_MODIFIER + * PRINTF_LEAST64_MODIFIER + * PRINTF_LEAST32_MODIFIER + * PRINTF_LEAST16_MODIFIER + * PRINTF_INTPTR_MODIFIER + * + * are strings which have been defined as the modifiers required + * for the "d", "u" and "x" printf formats to correctly output + * (u)intmax_t, (u)int64_t, (u)int32_t, (u)int16_t, (u)least64_t, + * (u)least32_t, (u)least16_t and (u)intptr_t types respectively. + * PRINTF_INTPTR_MODIFIER is not defined for some systems which + * provide their own stdint.h. PRINTF_INT64_MODIFIER is not + * defined if INT64_MAX is not defined. These are an extension + * beyond what C99 specifies must be in stdint.h. + * + * In addition, the following macros are defined: + * + * PRINTF_INTMAX_HEX_WIDTH + * PRINTF_INT64_HEX_WIDTH + * PRINTF_INT32_HEX_WIDTH + * PRINTF_INT16_HEX_WIDTH + * PRINTF_INT8_HEX_WIDTH + * PRINTF_INTMAX_DEC_WIDTH + * PRINTF_INT64_DEC_WIDTH + * PRINTF_INT32_DEC_WIDTH + * PRINTF_INT16_DEC_WIDTH + * PRINTF_INT8_DEC_WIDTH + * + * Which specifies the maximum number of characters required to + * print the number of that type in either hexadecimal or decimal. + * These are an extension beyond what C99 specifies must be in + * stdint.h. + * + * Compilers tested (all with 0 warnings at their highest respective + * settings): Borland Turbo C 2.0, WATCOM C/C++ 11.0 (16 bits and 32 + * bits), Microsoft Visual C++ 6.0 (32 bit), Microsoft Visual Studio + * .net (VC7), Intel C++ 4.0, GNU gcc v3.3.3 + * + * This file should be considered a work in progress. Suggestions for + * improvements, especially those which increase coverage are strongly + * encouraged. + * + * Acknowledgements + * + * The following people have made significant contributions to the + * development and testing of this file: + * + * Chris Howie + * John Steele Scott + * Dave Thorup + * + */ + +#include +#include +#include + +/* + * For gcc with _STDINT_H, fill in the PRINTF_INT*_MODIFIER macros, and + * do nothing else. On the Mac OS X version of gcc this is _STDINT_H_. + */ + +#if ((defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined (__WATCOMC__) && (defined (_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_)))) && !defined (_PSTDINT_H_INCLUDED) && !defined(_STDINT) +#include +#define _PSTDINT_H_INCLUDED +# ifndef PRINTF_INT64_MODIFIER +# define PRINTF_INT64_MODIFIER "ll" +# endif +# ifndef PRINTF_INT32_MODIFIER +# define PRINTF_INT32_MODIFIER "l" +# endif +# ifndef PRINTF_INT16_MODIFIER +# define PRINTF_INT16_MODIFIER "h" +# endif +# ifndef PRINTF_INTMAX_MODIFIER +# define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER +# endif +# ifndef PRINTF_INT64_HEX_WIDTH +# define PRINTF_INT64_HEX_WIDTH "16" +# endif +# ifndef PRINTF_INT32_HEX_WIDTH +# define PRINTF_INT32_HEX_WIDTH "8" +# endif +# ifndef PRINTF_INT16_HEX_WIDTH +# define PRINTF_INT16_HEX_WIDTH "4" +# endif +# ifndef PRINTF_INT8_HEX_WIDTH +# define PRINTF_INT8_HEX_WIDTH "2" +# endif +# ifndef PRINTF_INT64_DEC_WIDTH +# define PRINTF_INT64_DEC_WIDTH "20" +# endif +# ifndef PRINTF_INT32_DEC_WIDTH +# define PRINTF_INT32_DEC_WIDTH "10" +# endif +# ifndef PRINTF_INT16_DEC_WIDTH +# define PRINTF_INT16_DEC_WIDTH "5" +# endif +# ifndef PRINTF_INT8_DEC_WIDTH +# define PRINTF_INT8_DEC_WIDTH "3" +# endif +# ifndef PRINTF_INTMAX_HEX_WIDTH +# define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT64_HEX_WIDTH +# endif +# ifndef PRINTF_INTMAX_DEC_WIDTH +# define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT64_DEC_WIDTH +# endif + +/* + * Something really weird is going on with Open Watcom. Just pull some of + * these duplicated definitions from Open Watcom's stdint.h file for now. + */ + +# if defined (__WATCOMC__) && __WATCOMC__ >= 1250 +# if !defined (INT64_C) +# define INT64_C(x) (x + (INT64_MAX - INT64_MAX)) +# endif +# if !defined (UINT64_C) +# define UINT64_C(x) (x + (UINT64_MAX - UINT64_MAX)) +# endif +# if !defined (INT32_C) +# define INT32_C(x) (x + (INT32_MAX - INT32_MAX)) +# endif +# if !defined (UINT32_C) +# define UINT32_C(x) (x + (UINT32_MAX - UINT32_MAX)) +# endif +# if !defined (INT16_C) +# define INT16_C(x) (x) +# endif +# if !defined (UINT16_C) +# define UINT16_C(x) (x) +# endif +# if !defined (INT8_C) +# define INT8_C(x) (x) +# endif +# if !defined (UINT8_C) +# define UINT8_C(x) (x) +# endif +# if !defined (UINT64_MAX) +# define UINT64_MAX 18446744073709551615ULL +# endif +# if !defined (INT64_MAX) +# define INT64_MAX 9223372036854775807LL +# endif +# if !defined (UINT32_MAX) +# define UINT32_MAX 4294967295UL +# endif +# if !defined (INT32_MAX) +# define INT32_MAX 2147483647L +# endif +# if !defined (INTMAX_MAX) +# define INTMAX_MAX INT64_MAX +# endif +# if !defined (INTMAX_MIN) +# define INTMAX_MIN INT64_MIN +# endif +# endif +#endif + +#ifndef _PSTDINT_H_INCLUDED +#define _PSTDINT_H_INCLUDED + +#ifndef SIZE_MAX +# define SIZE_MAX (~(size_t)0) +#endif + +/* + * Deduce the type assignments from limits.h under the assumption that + * integer sizes in bits are powers of 2, and follow the ANSI + * definitions. + */ + +#ifndef UINT8_MAX +# define UINT8_MAX 0xff +#endif +#ifndef uint8_t +# if (UCHAR_MAX == UINT8_MAX) || defined (S_SPLINT_S) + typedef unsigned char uint8_t; +# define UINT8_C(v) ((uint8_t) v) +# else +# error "Platform not supported" +# endif +#endif + +#ifndef INT8_MAX +# define INT8_MAX 0x7f +#endif +#ifndef INT8_MIN +# define INT8_MIN INT8_C(0x80) +#endif +#ifndef int8_t +# if (SCHAR_MAX == INT8_MAX) || defined (S_SPLINT_S) + typedef signed char int8_t; +# define INT8_C(v) ((int8_t) v) +# else +# error "Platform not supported" +# endif +#endif + +#ifndef UINT16_MAX +# define UINT16_MAX 0xffff +#endif +#ifndef uint16_t +#if (UINT_MAX == UINT16_MAX) || defined (S_SPLINT_S) + typedef unsigned int uint16_t; +# ifndef PRINTF_INT16_MODIFIER +# define PRINTF_INT16_MODIFIER "" +# endif +# define UINT16_C(v) ((uint16_t) (v)) +#elif (USHRT_MAX == UINT16_MAX) + typedef unsigned short uint16_t; +# define UINT16_C(v) ((uint16_t) (v)) +# ifndef PRINTF_INT16_MODIFIER +# define PRINTF_INT16_MODIFIER "h" +# endif +#else +#error "Platform not supported" +#endif +#endif + +#ifndef INT16_MAX +# define INT16_MAX 0x7fff +#endif +#ifndef INT16_MIN +# define INT16_MIN INT16_C(0x8000) +#endif +#ifndef int16_t +#if (INT_MAX == INT16_MAX) || defined (S_SPLINT_S) + typedef signed int int16_t; +# define INT16_C(v) ((int16_t) (v)) +# ifndef PRINTF_INT16_MODIFIER +# define PRINTF_INT16_MODIFIER "" +# endif +#elif (SHRT_MAX == INT16_MAX) + typedef signed short int16_t; +# define INT16_C(v) ((int16_t) (v)) +# ifndef PRINTF_INT16_MODIFIER +# define PRINTF_INT16_MODIFIER "h" +# endif +#else +#error "Platform not supported" +#endif +#endif + +#ifndef UINT32_MAX +# define UINT32_MAX (0xffffffffUL) +#endif +#ifndef uint32_t +#if (ULONG_MAX == UINT32_MAX) || defined (S_SPLINT_S) + typedef unsigned long uint32_t; +# define UINT32_C(v) v ## UL +# ifndef PRINTF_INT32_MODIFIER +# define PRINTF_INT32_MODIFIER "l" +# endif +#elif (UINT_MAX == UINT32_MAX) + typedef unsigned int uint32_t; +# ifndef PRINTF_INT32_MODIFIER +# define PRINTF_INT32_MODIFIER "" +# endif +# define UINT32_C(v) v ## U +#elif (USHRT_MAX == UINT32_MAX) + typedef unsigned short uint32_t; +# define UINT32_C(v) ((unsigned short) (v)) +# ifndef PRINTF_INT32_MODIFIER +# define PRINTF_INT32_MODIFIER "" +# endif +#else +#error "Platform not supported" +#endif +#endif + +#ifndef INT32_MAX +# define INT32_MAX (0x7fffffffL) +#endif +#ifndef INT32_MIN +# define INT32_MIN INT32_C(0x80000000) +#endif +#ifndef int32_t +#if (LONG_MAX == INT32_MAX) || defined (S_SPLINT_S) + typedef signed long int32_t; +# define INT32_C(v) v ## L +# ifndef PRINTF_INT32_MODIFIER +# define PRINTF_INT32_MODIFIER "l" +# endif +#elif (INT_MAX == INT32_MAX) + typedef signed int int32_t; +# define INT32_C(v) v +# ifndef PRINTF_INT32_MODIFIER +# define PRINTF_INT32_MODIFIER "" +# endif +#elif (SHRT_MAX == INT32_MAX) + typedef signed short int32_t; +# define INT32_C(v) ((short) (v)) +# ifndef PRINTF_INT32_MODIFIER +# define PRINTF_INT32_MODIFIER "" +# endif +#else +#error "Platform not supported" +#endif +#endif + +/* + * The macro stdint_int64_defined is temporarily used to record + * whether or not 64 integer support is available. It must be + * defined for any 64 integer extensions for new platforms that are + * added. + */ + +#undef stdint_int64_defined +#if (defined(__STDC__) && defined(__STDC_VERSION__)) || defined (S_SPLINT_S) +# if (__STDC__ && __STDC_VERSION >= 199901L) || defined (S_SPLINT_S) +# define stdint_int64_defined + typedef long long int64_t; + typedef unsigned long long uint64_t; +# define UINT64_C(v) v ## ULL +# define INT64_C(v) v ## LL +# ifndef PRINTF_INT64_MODIFIER +# define PRINTF_INT64_MODIFIER "ll" +# endif +# endif +#endif + +#if !defined (stdint_int64_defined) +# if defined(__GNUC__) +# define stdint_int64_defined + __extension__ typedef long long int64_t; + __extension__ typedef unsigned long long uint64_t; +# define UINT64_C(v) v ## ULL +# define INT64_C(v) v ## LL +# ifndef PRINTF_INT64_MODIFIER +# define PRINTF_INT64_MODIFIER "ll" +# endif +# elif defined(__MWERKS__) || defined (__SUNPRO_C) || defined (__SUNPRO_CC) || defined (__APPLE_CC__) || defined (_LONG_LONG) || defined (_CRAYC) || defined (S_SPLINT_S) +# define stdint_int64_defined + typedef long long int64_t; + typedef unsigned long long uint64_t; +# define UINT64_C(v) v ## ULL +# define INT64_C(v) v ## LL +# ifndef PRINTF_INT64_MODIFIER +# define PRINTF_INT64_MODIFIER "ll" +# endif +# elif (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) || (defined(_MSC_VER) && _INTEGRAL_MAX_BITS >= 64) || (defined (__BORLANDC__) && __BORLANDC__ > 0x460) || defined (__alpha) || defined (__DECC) +# define stdint_int64_defined + typedef __int64 int64_t; + typedef unsigned __int64 uint64_t; +# define UINT64_C(v) v ## UI64 +# define INT64_C(v) v ## I64 +# ifndef PRINTF_INT64_MODIFIER +# define PRINTF_INT64_MODIFIER "I64" +# endif +# endif +#endif + +#if !defined (LONG_LONG_MAX) && defined (INT64_C) +# define LONG_LONG_MAX INT64_C (9223372036854775807) +#endif +#ifndef ULONG_LONG_MAX +# define ULONG_LONG_MAX UINT64_C (18446744073709551615) +#endif + +#if !defined (INT64_MAX) && defined (INT64_C) +# define INT64_MAX INT64_C (9223372036854775807) +#endif +#if !defined (INT64_MIN) && defined (INT64_C) +# define INT64_MIN INT64_C (-9223372036854775808) +#endif +#if !defined (UINT64_MAX) && defined (INT64_C) +# define UINT64_MAX UINT64_C (18446744073709551615) +#endif + +/* + * Width of hexadecimal for number field. + */ + +#ifndef PRINTF_INT64_HEX_WIDTH +# define PRINTF_INT64_HEX_WIDTH "16" +#endif +#ifndef PRINTF_INT32_HEX_WIDTH +# define PRINTF_INT32_HEX_WIDTH "8" +#endif +#ifndef PRINTF_INT16_HEX_WIDTH +# define PRINTF_INT16_HEX_WIDTH "4" +#endif +#ifndef PRINTF_INT8_HEX_WIDTH +# define PRINTF_INT8_HEX_WIDTH "2" +#endif + +#ifndef PRINTF_INT64_DEC_WIDTH +# define PRINTF_INT64_DEC_WIDTH "20" +#endif +#ifndef PRINTF_INT32_DEC_WIDTH +# define PRINTF_INT32_DEC_WIDTH "10" +#endif +#ifndef PRINTF_INT16_DEC_WIDTH +# define PRINTF_INT16_DEC_WIDTH "5" +#endif +#ifndef PRINTF_INT8_DEC_WIDTH +# define PRINTF_INT8_DEC_WIDTH "3" +#endif + +/* + * Ok, lets not worry about 128 bit integers for now. Moore's law says + * we don't need to worry about that until about 2040 at which point + * we'll have bigger things to worry about. + */ + +#ifdef stdint_int64_defined + typedef int64_t intmax_t; + typedef uint64_t uintmax_t; +# define INTMAX_MAX INT64_MAX +# define INTMAX_MIN INT64_MIN +# define UINTMAX_MAX UINT64_MAX +# define UINTMAX_C(v) UINT64_C(v) +# define INTMAX_C(v) INT64_C(v) +# ifndef PRINTF_INTMAX_MODIFIER +# define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER +# endif +# ifndef PRINTF_INTMAX_HEX_WIDTH +# define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT64_HEX_WIDTH +# endif +# ifndef PRINTF_INTMAX_DEC_WIDTH +# define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT64_DEC_WIDTH +# endif +#else + typedef int32_t intmax_t; + typedef uint32_t uintmax_t; +# define INTMAX_MAX INT32_MAX +# define UINTMAX_MAX UINT32_MAX +# define UINTMAX_C(v) UINT32_C(v) +# define INTMAX_C(v) INT32_C(v) +# ifndef PRINTF_INTMAX_MODIFIER +# define PRINTF_INTMAX_MODIFIER PRINTF_INT32_MODIFIER +# endif +# ifndef PRINTF_INTMAX_HEX_WIDTH +# define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT32_HEX_WIDTH +# endif +# ifndef PRINTF_INTMAX_DEC_WIDTH +# define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT32_DEC_WIDTH +# endif +#endif + +/* + * Because this file currently only supports platforms which have + * precise powers of 2 as bit sizes for the default integers, the + * least definitions are all trivial. Its possible that a future + * version of this file could have different definitions. + */ + +#ifndef stdint_least_defined + typedef int8_t int_least8_t; + typedef uint8_t uint_least8_t; + typedef int16_t int_least16_t; + typedef uint16_t uint_least16_t; + typedef int32_t int_least32_t; + typedef uint32_t uint_least32_t; +# define PRINTF_LEAST32_MODIFIER PRINTF_INT32_MODIFIER +# define PRINTF_LEAST16_MODIFIER PRINTF_INT16_MODIFIER +# define UINT_LEAST8_MAX UINT8_MAX +# define INT_LEAST8_MAX INT8_MAX +# define UINT_LEAST16_MAX UINT16_MAX +# define INT_LEAST16_MAX INT16_MAX +# define UINT_LEAST32_MAX UINT32_MAX +# define INT_LEAST32_MAX INT32_MAX +# define INT_LEAST8_MIN INT8_MIN +# define INT_LEAST16_MIN INT16_MIN +# define INT_LEAST32_MIN INT32_MIN +# ifdef stdint_int64_defined + typedef int64_t int_least64_t; + typedef uint64_t uint_least64_t; +# define PRINTF_LEAST64_MODIFIER PRINTF_INT64_MODIFIER +# define UINT_LEAST64_MAX UINT64_MAX +# define INT_LEAST64_MAX INT64_MAX +# define INT_LEAST64_MIN INT64_MIN +# endif +#endif +#undef stdint_least_defined + +/* + * The ANSI C committee pretending to know or specify anything about + * performance is the epitome of misguided arrogance. The mandate of + * this file is to *ONLY* ever support that absolute minimum + * definition of the fast integer types, for compatibility purposes. + * No extensions, and no attempt to suggest what may or may not be a + * faster integer type will ever be made in this file. Developers are + * warned to stay away from these types when using this or any other + * stdint.h. + */ + +typedef int_least8_t int_fast8_t; +typedef uint_least8_t uint_fast8_t; +typedef int_least16_t int_fast16_t; +typedef uint_least16_t uint_fast16_t; +typedef int_least32_t int_fast32_t; +typedef uint_least32_t uint_fast32_t; +#define UINT_FAST8_MAX UINT_LEAST8_MAX +#define INT_FAST8_MAX INT_LEAST8_MAX +#define UINT_FAST16_MAX UINT_LEAST16_MAX +#define INT_FAST16_MAX INT_LEAST16_MAX +#define UINT_FAST32_MAX UINT_LEAST32_MAX +#define INT_FAST32_MAX INT_LEAST32_MAX +#define INT_FAST8_MIN INT_LEAST8_MIN +#define INT_FAST16_MIN INT_LEAST16_MIN +#define INT_FAST32_MIN INT_LEAST32_MIN +#ifdef stdint_int64_defined + typedef int_least64_t int_fast64_t; + typedef uint_least64_t uint_fast64_t; +# define UINT_FAST64_MAX UINT_LEAST64_MAX +# define INT_FAST64_MAX INT_LEAST64_MAX +# define INT_FAST64_MIN INT_LEAST64_MIN +#endif + +#undef stdint_int64_defined + +/* + * Whatever piecemeal, per compiler thing we can do about the wchar_t + * type limits. + */ + +#if defined(__WATCOMC__) || defined(_MSC_VER) || defined (__GNUC__) +# include +# ifndef WCHAR_MIN +# define WCHAR_MIN 0 +# endif +# ifndef WCHAR_MAX +# define WCHAR_MAX ((wchar_t)-1) +# endif +#endif + +/* + * Whatever piecemeal, per compiler/platform thing we can do about the + * (u)intptr_t types and limits. + */ + +#if defined (_MSC_VER) && defined (_UINTPTR_T_DEFINED) +# define STDINT_H_UINTPTR_T_DEFINED +#endif + +#ifndef STDINT_H_UINTPTR_T_DEFINED +# if defined (__alpha__) || defined (__ia64__) || defined (__x86_64__) || defined (_WIN64) +# define stdint_intptr_bits 64 +# elif defined (__WATCOMC__) || defined (__TURBOC__) +# if defined(__TINY__) || defined(__SMALL__) || defined(__MEDIUM__) +# define stdint_intptr_bits 16 +# else +# define stdint_intptr_bits 32 +# endif +# elif defined (__i386__) || defined (_WIN32) || defined (WIN32) +# define stdint_intptr_bits 32 +# elif defined (__INTEL_COMPILER) +/* TODO -- what will Intel do about x86-64? */ +# endif + +# ifdef stdint_intptr_bits +# define stdint_intptr_glue3_i(a,b,c) a##b##c +# define stdint_intptr_glue3(a,b,c) stdint_intptr_glue3_i(a,b,c) +# ifndef PRINTF_INTPTR_MODIFIER +# define PRINTF_INTPTR_MODIFIER stdint_intptr_glue3(PRINTF_INT,stdint_intptr_bits,_MODIFIER) +# endif +# ifndef PTRDIFF_MAX +# define PTRDIFF_MAX stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX) +# endif +# ifndef PTRDIFF_MIN +# define PTRDIFF_MIN stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN) +# endif +# ifndef UINTPTR_MAX +# define UINTPTR_MAX stdint_intptr_glue3(UINT,stdint_intptr_bits,_MAX) +# endif +# ifndef INTPTR_MAX +# define INTPTR_MAX stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX) +# endif +# ifndef INTPTR_MIN +# define INTPTR_MIN stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN) +# endif +# ifndef INTPTR_C +# define INTPTR_C(x) stdint_intptr_glue3(INT,stdint_intptr_bits,_C)(x) +# endif +# ifndef UINTPTR_C +# define UINTPTR_C(x) stdint_intptr_glue3(UINT,stdint_intptr_bits,_C)(x) +# endif + typedef stdint_intptr_glue3(uint,stdint_intptr_bits,_t) uintptr_t; + typedef stdint_intptr_glue3( int,stdint_intptr_bits,_t) intptr_t; +# else +/* TODO -- This following is likely wrong for some platforms, and does + nothing for the definition of uintptr_t. */ + typedef ptrdiff_t intptr_t; +# endif +# define STDINT_H_UINTPTR_T_DEFINED +#endif + +/* + * Assumes sig_atomic_t is signed and we have a 2s complement machine. + */ + +#ifndef SIG_ATOMIC_MAX +# define SIG_ATOMIC_MAX ((((sig_atomic_t) 1) << (sizeof (sig_atomic_t)*CHAR_BIT-1)) - 1) +#endif + +#endif + diff --git a/include/assimp/port/AndroidJNI/AndroidJNIIOSystem.h b/include/assimp/port/AndroidJNI/AndroidJNIIOSystem.h index ad6940253..53aa2b844 100644 --- a/include/assimp/port/AndroidJNI/AndroidJNIIOSystem.h +++ b/include/assimp/port/AndroidJNI/AndroidJNIIOSystem.h @@ -1,92 +1,92 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2012, assimp team -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file Android implementation of IOSystem using the standard C file functions. - * Aimed to ease the acces to android assets */ - -#if __ANDROID__ and __ANDROID_API__ > 9 and defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT) -#ifndef AI_ANDROIDJNIIOSYSTEM_H_INC -#define AI_ANDROIDJNIIOSYSTEM_H_INC - -#include "../code/DefaultIOSystem.h" -#include -#include -#include - -namespace Assimp { - -// --------------------------------------------------------------------------- -/** Android extension to DefaultIOSystem using the standard C file functions */ -class AndroidJNIIOSystem : public DefaultIOSystem -{ -public: - - /** Initialize android activity data */ - std::string mApkWorkspacePath; - AAssetManager* mApkAssetManager; - - /** Constructor. */ - AndroidJNIIOSystem(ANativeActivity* activity); - - /** Destructor. */ - ~AndroidJNIIOSystem(); - - // ------------------------------------------------------------------- - /** Tests for the existence of a file at the given path. */ - bool Exists( const char* pFile) const; - - // ------------------------------------------------------------------- - /** Opens a file at the given path, with given mode */ - IOStream* Open( const char* strFile, const char* strMode); - - // ------------------------------------------------------------------------------------------------ - // Inits Android extractor - void AndroidActivityInit(ANativeActivity* activity); - - // ------------------------------------------------------------------------------------------------ - // Extracts android asset - bool AndroidExtractAsset(std::string name); - -}; - -} //!ns Assimp - -#endif //AI_ANDROIDJNIIOSYSTEM_H_INC -#endif //__ANDROID__ and __ANDROID_API__ > 9 and defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT) +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file Android implementation of IOSystem using the standard C file functions. + * Aimed to ease the acces to android assets */ + +#if __ANDROID__ and __ANDROID_API__ > 9 and defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT) +#ifndef AI_ANDROIDJNIIOSYSTEM_H_INC +#define AI_ANDROIDJNIIOSYSTEM_H_INC + +#include "../code/DefaultIOSystem.h" +#include +#include +#include + +namespace Assimp { + +// --------------------------------------------------------------------------- +/** Android extension to DefaultIOSystem using the standard C file functions */ +class AndroidJNIIOSystem : public DefaultIOSystem +{ +public: + + /** Initialize android activity data */ + std::string mApkWorkspacePath; + AAssetManager* mApkAssetManager; + + /** Constructor. */ + AndroidJNIIOSystem(ANativeActivity* activity); + + /** Destructor. */ + ~AndroidJNIIOSystem(); + + // ------------------------------------------------------------------- + /** Tests for the existence of a file at the given path. */ + bool Exists( const char* pFile) const; + + // ------------------------------------------------------------------- + /** Opens a file at the given path, with given mode */ + IOStream* Open( const char* strFile, const char* strMode); + + // ------------------------------------------------------------------------------------------------ + // Inits Android extractor + void AndroidActivityInit(ANativeActivity* activity); + + // ------------------------------------------------------------------------------------------------ + // Extracts android asset + bool AndroidExtractAsset(std::string name); + +}; + +} //!ns Assimp + +#endif //AI_ANDROIDJNIIOSYSTEM_H_INC +#endif //__ANDROID__ and __ANDROID_API__ > 9 and defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT) diff --git a/packaging/windows-innosetup/howto-build-setup.txt b/packaging/windows-innosetup/howto-build-setup.txt index 4b16eb4ef..d089c0cb4 100644 --- a/packaging/windows-innosetup/howto-build-setup.txt +++ b/packaging/windows-innosetup/howto-build-setup.txt @@ -1,16 +1,16 @@ - -How to build the Assimp installer using Inno Setup - - -1) Get MS VC 2008 SP1 redist packages for x86 and amd64 and copy 'em right here. - -vcredist_x86.exe -vcredist_x64.exe - -2) Get D3DCompiler_NN.dll and D3DX9_NN.dll from a) your system32 folder and b) your SysWOW64 folder. Copy all 4 here. Rename the 64 bit files to _x64.dll. NN is the D3DX version targeted by your DX SDK. If it is not 42, you need to update the Inno setup script (script.iss) as well. If you don't have a 64 bit Windows, get the DLLs from somebody else. Please don't ask google because many DLL downloads are infected. - -3) Build assimp, assimpcmd and assimpview for the 'release-dll' target and both the Win32 and x64 architectures. - -4) Get Inno Setup -5) Compile, output is written to the 'out' folder. - + +How to build the Assimp installer using Inno Setup + + +1) Get MS VC 2008 SP1 redist packages for x86 and amd64 and copy 'em right here. + +vcredist_x86.exe +vcredist_x64.exe + +2) Get D3DCompiler_NN.dll and D3DX9_NN.dll from a) your system32 folder and b) your SysWOW64 folder. Copy all 4 here. Rename the 64 bit files to _x64.dll. NN is the D3DX version targeted by your DX SDK. If it is not 42, you need to update the Inno setup script (script.iss) as well. If you don't have a 64 bit Windows, get the DLLs from somebody else. Please don't ask google because many DLL downloads are infected. + +3) Build assimp, assimpcmd and assimpview for the 'release-dll' target and both the Win32 and x64 architectures. + +4) Get Inno Setup +5) Compile, output is written to the 'out' folder. + diff --git a/packaging/windows-innosetup/readme_installer.txt b/packaging/windows-innosetup/readme_installer.txt index 397fae3dc..6ea969dc1 100644 --- a/packaging/windows-innosetup/readme_installer.txt +++ b/packaging/windows-innosetup/readme_installer.txt @@ -1,23 +1,23 @@ - ------------------------------------------------------------------------------------- -Open Asset Import Library (Assimp) SDK Installer -Release Notes ------------------------------------------------------------------------------------- - -http://assimp.sf.net - - -Troubleshooting -=============== - -1. Missing d3dx9_(some-number).dll? -Install the latest DirectX runtime or grab the file from somewhere (that's evil but mostly fine). - -2. Application configuration not correct / missing msvcr***.dll? -Reinstall Microsoft Visual C++ 2005 SP1 Redistributable (x86 or x64, depending on your system) - -3. assimp.exe not in PATH -Add it to PATH. That's not a bug, the installer does not alter the PATH. - -4. Crashes immediately -You CPU lacks SSE2 support. Build Assimp from scratch to suit your CPU, sorry. + +------------------------------------------------------------------------------------ +Open Asset Import Library (Assimp) SDK Installer +Release Notes +------------------------------------------------------------------------------------ + +http://assimp.sf.net + + +Troubleshooting +=============== + +1. Missing d3dx9_(some-number).dll? +Install the latest DirectX runtime or grab the file from somewhere (that's evil but mostly fine). + +2. Application configuration not correct / missing msvcr***.dll? +Reinstall Microsoft Visual C++ 2005 SP1 Redistributable (x86 or x64, depending on your system) + +3. assimp.exe not in PATH +Add it to PATH. That's not a bug, the installer does not alter the PATH. + +4. Crashes immediately +You CPU lacks SSE2 support. Build Assimp from scratch to suit your CPU, sorry. diff --git a/packaging/windows-innosetup/readme_installer_vieweronly.txt b/packaging/windows-innosetup/readme_installer_vieweronly.txt index c1ff3716a..bfa4f8c9e 100644 --- a/packaging/windows-innosetup/readme_installer_vieweronly.txt +++ b/packaging/windows-innosetup/readme_installer_vieweronly.txt @@ -1,32 +1,32 @@ - ------------------------------------------------------------------------------------- -Open Asset Import Library (Assimp) Viewer Installer -Release Notes ------------------------------------------------------------------------------------- - -http://assimp.sf.net - -Known Bugs & Limitations -======================== - -Viewer - -- Normals appear flipped from time to time when either of the normals-related menu items was hit. -- Alpha-sorting is implemented, but still causes artifacts when models are moved quickly. -- Several important texture file formats (such as GIF) are not supported. -- HUD is blurred on the right side. ATI/AMD hardware only. - -Troubleshooting -=============== - -1. Missing d3dx9_(number).dll? -Install the latest DirectX runtime or grab the file from somewhere (that's evil but mostly fine). - -2. Application configuration not correct / missing msvcr***.dll? -Reinstall Microsoft Visual C++ 2005 SP1 Redistributable (x86 or x64, depending on your system) - -3. assimp.exe not in PATH -Add it to PATH. That's not a bug, the installer does not alter the PATH. - -4. Crashes immediately + +------------------------------------------------------------------------------------ +Open Asset Import Library (Assimp) Viewer Installer +Release Notes +------------------------------------------------------------------------------------ + +http://assimp.sf.net + +Known Bugs & Limitations +======================== + +Viewer + +- Normals appear flipped from time to time when either of the normals-related menu items was hit. +- Alpha-sorting is implemented, but still causes artifacts when models are moved quickly. +- Several important texture file formats (such as GIF) are not supported. +- HUD is blurred on the right side. ATI/AMD hardware only. + +Troubleshooting +=============== + +1. Missing d3dx9_(number).dll? +Install the latest DirectX runtime or grab the file from somewhere (that's evil but mostly fine). + +2. Application configuration not correct / missing msvcr***.dll? +Reinstall Microsoft Visual C++ 2005 SP1 Redistributable (x86 or x64, depending on your system) + +3. assimp.exe not in PATH +Add it to PATH. That's not a bug, the installer does not alter the PATH. + +4. Crashes immediately You CPU lacks SSE2 support. Build Assimp from scratch to suit your CPU, sorry. \ No newline at end of file diff --git a/packaging/windows-mkzip/bin_readme.txt b/packaging/windows-mkzip/bin_readme.txt index 3b185cfed..10839a3d9 100644 --- a/packaging/windows-mkzip/bin_readme.txt +++ b/packaging/windows-mkzip/bin_readme.txt @@ -1,29 +1,29 @@ - ------------------------------------------------------------------------------------- -Open Asset Import Library (Assimp) Tools/Binaries for Windows -Release Notes ------------------------------------------------------------------------------------- - - -Known Bugs & Limitations -======================== - -Viewer - -- For files more than one embedded texture, only the first is loaded. -- Normals appear flipped from time to time when either of the normals-related menu items was hit. -- Alpha-sorting is implemented, but still causes artifacts when models are moved quickly. -- Several important texture file formats (such as GIF) are not supported. -- HUD is blurred on the right side. ATI/AMD hardware only. - -Troubleshooting -=============== - -1. Missing d3dx9_42.dll? -Install the latest DirectX runtime or grab the file from somewhere (that's evil but mostly fine). - -2. Application configuration not correct / missing msv*** DLLs? -(Re)install Microsoft Visual C++ 2005 SP1 Redistributable (x86 or x64, depending on your system) - -3. Crashes immediately + +------------------------------------------------------------------------------------ +Open Asset Import Library (Assimp) Tools/Binaries for Windows +Release Notes +------------------------------------------------------------------------------------ + + +Known Bugs & Limitations +======================== + +Viewer + +- For files more than one embedded texture, only the first is loaded. +- Normals appear flipped from time to time when either of the normals-related menu items was hit. +- Alpha-sorting is implemented, but still causes artifacts when models are moved quickly. +- Several important texture file formats (such as GIF) are not supported. +- HUD is blurred on the right side. ATI/AMD hardware only. + +Troubleshooting +=============== + +1. Missing d3dx9_42.dll? +Install the latest DirectX runtime or grab the file from somewhere (that's evil but mostly fine). + +2. Application configuration not correct / missing msv*** DLLs? +(Re)install Microsoft Visual C++ 2005 SP1 Redistributable (x86 or x64, depending on your system) + +3. Crashes immediately You CPU lacks SSE2 support. Build Assimp from scratch to suit your CPU, sorry. \ No newline at end of file diff --git a/port/AndroidJNI/AndroidJNIIOSystem.cpp b/port/AndroidJNI/AndroidJNIIOSystem.cpp index 4a149e050..f9ba94cb1 100644 --- a/port/AndroidJNI/AndroidJNIIOSystem.cpp +++ b/port/AndroidJNI/AndroidJNIIOSystem.cpp @@ -1,175 +1,175 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2012, assimp team - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file Android extension of DefaultIOSystem using the standard C file functions */ - - -#include -#include -#if __ANDROID__ and __ANDROID_API__ > 9 and defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT) - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace Assimp; - -// ------------------------------------------------------------------------------------------------ -// Constructor. -AndroidJNIIOSystem::AndroidJNIIOSystem(ANativeActivity* activity) -{ - AndroidActivityInit(activity); -} - -// ------------------------------------------------------------------------------------------------ -// Destructor. -AndroidJNIIOSystem::~AndroidJNIIOSystem() -{ - // nothing to do here -} - -// ------------------------------------------------------------------------------------------------ -// Tests for the existence of a file at the given path. -bool AndroidJNIIOSystem::Exists( const char* pFile) const -{ - AAsset* asset = AAssetManager_open(mApkAssetManager, pFile, - AASSET_MODE_UNKNOWN); - FILE* file = ::fopen( (mApkWorkspacePath + getOsSeparator() + std::string(pFile)).c_str(), "rb"); - - if (!asset && !file) - { - __android_log_print(ANDROID_LOG_ERROR, "Assimp", "Asset manager can not find: %s", pFile); - return false; - } - - __android_log_print(ANDROID_LOG_ERROR, "Assimp", "Asset exists"); - if (file) - ::fclose( file); - return true; -} - -// ------------------------------------------------------------------------------------------------ -// Inits Android extractor -void AndroidJNIIOSystem::AndroidActivityInit(ANativeActivity* activity) -{ - mApkWorkspacePath = activity->internalDataPath; - mApkAssetManager = activity->assetManager; -} - -// ------------------------------------------------------------------------------------------------ -// Extracts android asset -bool AndroidJNIIOSystem::AndroidExtractAsset(std::string name) -{ - std::string newPath = mApkWorkspacePath + getOsSeparator() + name; - - DefaultIOSystem io; - - // Do not extract if extracted already - if ( io.Exists(newPath.c_str()) ) { - __android_log_print(ANDROID_LOG_DEFAULT, "Assimp", "Asset already extracted"); - return true; - } - // Open file - AAsset* asset = AAssetManager_open(mApkAssetManager, name.c_str(), - AASSET_MODE_UNKNOWN); - std::vector assetContent; - - if (asset != NULL) { - // Find size - off_t assetSize = AAsset_getLength(asset); - - // Prepare input buffer - assetContent.resize(assetSize); - - // Store input buffer - AAsset_read(asset, &assetContent[0], assetSize); - - // Close - AAsset_close(asset); - - // Prepare output buffer - std::ofstream assetExtracted(newPath.c_str(), - std::ios::out | std::ios::binary); - if (!assetExtracted) { - __android_log_print(ANDROID_LOG_ERROR, "assimp", - "Can not open output file"); - } - - // Write output buffer into a file - assetExtracted.write(&assetContent[0], assetContent.size()); - assetExtracted.close(); - - __android_log_print(ANDROID_LOG_DEFAULT, "Assimp", "Asset extracted"); - } else { - __android_log_print(ANDROID_LOG_ERROR, "assimp", "Asset not found: %s", name.c_str()); - return false; - } - return true; -} - -// ------------------------------------------------------------------------------------------------ -// Open a new file with a given path. -IOStream* AndroidJNIIOSystem::Open( const char* strFile, const char* strMode) -{ - ai_assert(NULL != strFile); - ai_assert(NULL != strMode); - - std::string fullPath(mApkWorkspacePath + getOsSeparator() + std::string(strFile)); - if (Exists(strFile)) - AndroidExtractAsset(std::string(strFile)); - - FILE* file = ::fopen( fullPath.c_str(), strMode); - - if( NULL == file) - return NULL; - - __android_log_print(ANDROID_LOG_ERROR, "assimp", "AndroidIOSystem: file %s opened", fullPath.c_str()); - return new DefaultIOStream(file, fullPath); -} - -#undef PATHLIMIT -#endif // __ANDROID__ and __ANDROID_API__ > 9 and defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT) +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +/** @file Android extension of DefaultIOSystem using the standard C file functions */ + + +#include +#include +#if __ANDROID__ and __ANDROID_API__ > 9 and defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT) + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace Assimp; + +// ------------------------------------------------------------------------------------------------ +// Constructor. +AndroidJNIIOSystem::AndroidJNIIOSystem(ANativeActivity* activity) +{ + AndroidActivityInit(activity); +} + +// ------------------------------------------------------------------------------------------------ +// Destructor. +AndroidJNIIOSystem::~AndroidJNIIOSystem() +{ + // nothing to do here +} + +// ------------------------------------------------------------------------------------------------ +// Tests for the existence of a file at the given path. +bool AndroidJNIIOSystem::Exists( const char* pFile) const +{ + AAsset* asset = AAssetManager_open(mApkAssetManager, pFile, + AASSET_MODE_UNKNOWN); + FILE* file = ::fopen( (mApkWorkspacePath + getOsSeparator() + std::string(pFile)).c_str(), "rb"); + + if (!asset && !file) + { + __android_log_print(ANDROID_LOG_ERROR, "Assimp", "Asset manager can not find: %s", pFile); + return false; + } + + __android_log_print(ANDROID_LOG_ERROR, "Assimp", "Asset exists"); + if (file) + ::fclose( file); + return true; +} + +// ------------------------------------------------------------------------------------------------ +// Inits Android extractor +void AndroidJNIIOSystem::AndroidActivityInit(ANativeActivity* activity) +{ + mApkWorkspacePath = activity->internalDataPath; + mApkAssetManager = activity->assetManager; +} + +// ------------------------------------------------------------------------------------------------ +// Extracts android asset +bool AndroidJNIIOSystem::AndroidExtractAsset(std::string name) +{ + std::string newPath = mApkWorkspacePath + getOsSeparator() + name; + + DefaultIOSystem io; + + // Do not extract if extracted already + if ( io.Exists(newPath.c_str()) ) { + __android_log_print(ANDROID_LOG_DEFAULT, "Assimp", "Asset already extracted"); + return true; + } + // Open file + AAsset* asset = AAssetManager_open(mApkAssetManager, name.c_str(), + AASSET_MODE_UNKNOWN); + std::vector assetContent; + + if (asset != NULL) { + // Find size + off_t assetSize = AAsset_getLength(asset); + + // Prepare input buffer + assetContent.resize(assetSize); + + // Store input buffer + AAsset_read(asset, &assetContent[0], assetSize); + + // Close + AAsset_close(asset); + + // Prepare output buffer + std::ofstream assetExtracted(newPath.c_str(), + std::ios::out | std::ios::binary); + if (!assetExtracted) { + __android_log_print(ANDROID_LOG_ERROR, "assimp", + "Can not open output file"); + } + + // Write output buffer into a file + assetExtracted.write(&assetContent[0], assetContent.size()); + assetExtracted.close(); + + __android_log_print(ANDROID_LOG_DEFAULT, "Assimp", "Asset extracted"); + } else { + __android_log_print(ANDROID_LOG_ERROR, "assimp", "Asset not found: %s", name.c_str()); + return false; + } + return true; +} + +// ------------------------------------------------------------------------------------------------ +// Open a new file with a given path. +IOStream* AndroidJNIIOSystem::Open( const char* strFile, const char* strMode) +{ + ai_assert(NULL != strFile); + ai_assert(NULL != strMode); + + std::string fullPath(mApkWorkspacePath + getOsSeparator() + std::string(strFile)); + if (Exists(strFile)) + AndroidExtractAsset(std::string(strFile)); + + FILE* file = ::fopen( fullPath.c_str(), strMode); + + if( NULL == file) + return NULL; + + __android_log_print(ANDROID_LOG_ERROR, "assimp", "AndroidIOSystem: file %s opened", fullPath.c_str()); + return new DefaultIOStream(file, fullPath); +} + +#undef PATHLIMIT +#endif // __ANDROID__ and __ANDROID_API__ > 9 and defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT) diff --git a/port/AssimpDelphi/Readme.txt b/port/AssimpDelphi/Readme.txt index c9aed7b0f..07d6935ae 100644 --- a/port/AssimpDelphi/Readme.txt +++ b/port/AssimpDelphi/Readme.txt @@ -1,6 +1,6 @@ -This is a set of Delphi units for using the Assimp C DLL. This was created for use with Delphi 7, but should be usable as-is or with minimal modifications with later Delphi versions. - -This set of headers is enough to load and display a model with external textures. Since I'm not familiar with animated models and some of the other functionality of the assimp library, I did not convert the headers for those features. - -See http://sourceforge.net/tracker/?func=detail&aid=3212646&group_id=226462&atid=1067634 for the original patch - +This is a set of Delphi units for using the Assimp C DLL. This was created for use with Delphi 7, but should be usable as-is or with minimal modifications with later Delphi versions. + +This set of headers is enough to load and display a model with external textures. Since I'm not familiar with animated models and some of the other functionality of the assimp library, I did not convert the headers for those features. + +See http://sourceforge.net/tracker/?func=detail&aid=3212646&group_id=226462&atid=1067634 for the original patch + diff --git a/samples/DevIL/include/IL/ilut_config.h b/samples/DevIL/include/IL/ilut_config.h index a05da54c1..2b3625b86 100644 --- a/samples/DevIL/include/IL/ilut_config.h +++ b/samples/DevIL/include/IL/ilut_config.h @@ -1,26 +1,26 @@ -#ifndef __ILUT_CONFIG_H__ -#define __ILUT_CONFIG_H__ - -#define IL_USE_PRAGMA_LIBS - -// Supported APIs (ILUT) - -// -// sorry just -// cant get this one to work under windows -// have disabled for the now -// -// will look at it some more later -// -// Kriss -// -#undef ILUT_USE_ALLEGRO - -#undef ILUT_USE_DIRECTX8 -//#define ILUT_USE_DIRECTX9 -//#define ILUT_USE_DIRECTX10 -#define ILUT_USE_OPENGL -//#define ILUT_USE_SDL -#define ILUT_USE_WIN32 - -#endif//__ILUT_CONFIG_H__ +#ifndef __ILUT_CONFIG_H__ +#define __ILUT_CONFIG_H__ + +#define IL_USE_PRAGMA_LIBS + +// Supported APIs (ILUT) + +// +// sorry just +// cant get this one to work under windows +// have disabled for the now +// +// will look at it some more later +// +// Kriss +// +#undef ILUT_USE_ALLEGRO + +#undef ILUT_USE_DIRECTX8 +//#define ILUT_USE_DIRECTX9 +//#define ILUT_USE_DIRECTX10 +#define ILUT_USE_OPENGL +//#define ILUT_USE_SDL +#define ILUT_USE_WIN32 + +#endif//__ILUT_CONFIG_H__ diff --git a/samples/SimpleTexturedOpenGL/SimpleTexturedOpenGL/src/model_loading.cpp b/samples/SimpleTexturedOpenGL/SimpleTexturedOpenGL/src/model_loading.cpp index 2787fad52..bac800152 100644 --- a/samples/SimpleTexturedOpenGL/SimpleTexturedOpenGL/src/model_loading.cpp +++ b/samples/SimpleTexturedOpenGL/SimpleTexturedOpenGL/src/model_loading.cpp @@ -1,882 +1,882 @@ -// ---------------------------------------------------------------------------- -// Another Assimp OpenGL sample including texturing. -// Note that it is very basic and will only read and apply the model's diffuse -// textures (by their material ids) -// -// Don't worry about the "Couldn't load Image: ...dwarf2.jpg" Message. -// It's caused by a bad texture reference in the model file (I guess) -// -// If you intend to _use_ this code sample in your app, do yourself a favour -// and replace immediate mode calls with VBOs ... -// -// Thanks to NeHe on whose OpenGL tutorials this one's based on! :) -// http://nehe.gamedev.net/ -// ---------------------------------------------------------------------------- -#include -#include -#include -#include -#include - -#include - -//to map image filenames to textureIds -#include -#include - - -// assimp include files. These three are usually needed. -#include "assimp/Importer.hpp" //OO version Header! -#include "assimp/postprocess.h" -#include "assimp/scene.h" -#include "assimp/DefaultLogger.hpp" -#include "assimp/LogStream.hpp" - - -// The default hard-coded path. Can be overridden by supplying a path through the command line. -static std::string modelpath = "../../test/models/OBJ/spider.obj"; - - -HGLRC hRC=NULL; // Permanent Rendering Context -HDC hDC=NULL; // Private GDI Device Context -HWND hWnd=NULL; // Holds Window Handle -HINSTANCE hInstance; // Holds The Instance Of The Application - -bool keys[256]; // Array used for Keyboard Routine; -bool active=TRUE; // Window Active Flag Set To TRUE by Default -bool fullscreen=TRUE; // full-screen Flag Set To full-screen By Default - -GLfloat xrot; -GLfloat yrot; -GLfloat zrot; - - -LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration For WndProc -GLboolean abortGLInit(const char*); - -const char* windowTitle = "OpenGL Framework"; - -GLfloat LightAmbient[]= { 0.5f, 0.5f, 0.5f, 1.0f }; -GLfloat LightDiffuse[]= { 1.0f, 1.0f, 1.0f, 1.0f }; -GLfloat LightPosition[]= { 0.0f, 0.0f, 15.0f, 1.0f }; - - - -// the global Assimp scene object -const aiScene* scene = NULL; -GLuint scene_list = 0; -aiVector3D scene_min, scene_max, scene_center; - -// images / texture -std::map textureIdMap; // map image filenames to textureIds -GLuint* textureIds; // pointer to texture Array - -// Create an instance of the Importer class -Assimp::Importer importer; - - -void createAILogger() -{ - // Change this line to normal if you not want to analyse the import process - //Assimp::Logger::LogSeverity severity = Assimp::Logger::NORMAL; - Assimp::Logger::LogSeverity severity = Assimp::Logger::VERBOSE; - - // Create a logger instance for Console Output - Assimp::DefaultLogger::create("",severity, aiDefaultLogStream_STDOUT); - - // Create a logger instance for File Output (found in project folder or near .exe) - Assimp::DefaultLogger::create("assimp_log.txt",severity, aiDefaultLogStream_FILE); - - // Now I am ready for logging my stuff - Assimp::DefaultLogger::get()->info("this is my info-call"); -} - -void destroyAILogger() -{ - // Kill it after the work is done - Assimp::DefaultLogger::kill(); -} - -void logInfo(std::string logString) -{ - // Will add message to File with "info" Tag - Assimp::DefaultLogger::get()->info(logString.c_str()); -} - -void logDebug(const char* logString) -{ - // Will add message to File with "debug" Tag - Assimp::DefaultLogger::get()->debug(logString); -} - - -bool Import3DFromFile( const std::string& pFile) -{ - // Check if file exists - std::ifstream fin(pFile.c_str()); - if(!fin.fail()) - { - fin.close(); - } - else - { - MessageBox(NULL, ("Couldn't open file: " + pFile).c_str() , "ERROR", MB_OK | MB_ICONEXCLAMATION); - logInfo( importer.GetErrorString()); - return false; - } - - scene = importer.ReadFile( pFile, aiProcessPreset_TargetRealtime_Quality); - - // If the import failed, report it - if( !scene) - { - logInfo( importer.GetErrorString()); - return false; - } - - // Now we can access the file's contents. - logInfo("Import of scene " + pFile + " succeeded."); - - // We're done. Everything will be cleaned up by the importer destructor - return true; -} - -// Resize And Initialize The GL Window -void ReSizeGLScene(GLsizei width, GLsizei height) -{ - // Prevent A Divide By Zero By - if (height==0) - { - // Making Height Equal One - height=1; - } - - glViewport(0, 0, width, height); // Reset The Current Viewport - - glMatrixMode(GL_PROJECTION); // Select The Projection Matrix - glLoadIdentity(); // Reset The Projection Matrix - - // Calculate The Aspect Ratio Of The Window - gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f); - - glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix - glLoadIdentity(); // Reset The Modelview Matrix -} - - -std::string getBasePath(const std::string& path) -{ - size_t pos = path.find_last_of("\\/"); - return (std::string::npos == pos) ? "" : path.substr(0, pos + 1); -} - -int LoadGLTextures(const aiScene* scene) -{ - ILboolean success; - - /* Before calling ilInit() version should be checked. */ - if (ilGetInteger(IL_VERSION_NUM) < IL_VERSION) - { - /// wrong DevIL version /// - std::string err_msg = "Wrong DevIL version. Old devil.dll in system32/SysWow64?"; - char* cErr_msg = (char *) err_msg.c_str(); - abortGLInit(cErr_msg); - return -1; - } - - ilInit(); /* Initialization of DevIL */ - - if (scene->HasTextures()) abortGLInit("Support for meshes with embedded textures is not implemented"); - - /* getTexture Filenames and Numb of Textures */ - for (unsigned int m=0; mmNumMaterials; m++) - { - int texIndex = 0; - aiReturn texFound = AI_SUCCESS; - - aiString path; // filename - - while (texFound == AI_SUCCESS) - { - texFound = scene->mMaterials[m]->GetTexture(aiTextureType_DIFFUSE, texIndex, &path); - textureIdMap[path.data] = NULL; //fill map with textures, pointers still NULL yet - texIndex++; - } - } - - int numTextures = textureIdMap.size(); - - /* array with DevIL image IDs */ - ILuint* imageIds = NULL; - imageIds = new ILuint[numTextures]; - - /* generate DevIL Image IDs */ - ilGenImages(numTextures, imageIds); /* Generation of numTextures image names */ - - /* create and fill array with GL texture ids */ - textureIds = new GLuint[numTextures]; - glGenTextures(numTextures, textureIds); /* Texture name generation */ - - /* get iterator */ - std::map::iterator itr = textureIdMap.begin(); - - std::string basepath = getBasePath(modelpath); - for (int i=0; ir, color->g, color->b, color->a); -} - -void set_float4(float f[4], float a, float b, float c, float d) -{ - f[0] = a; - f[1] = b; - f[2] = c; - f[3] = d; -} - -void color4_to_float4(const aiColor4D *c, float f[4]) -{ - f[0] = c->r; - f[1] = c->g; - f[2] = c->b; - f[3] = c->a; -} - -void apply_material(const aiMaterial *mtl) -{ - float c[4]; - - GLenum fill_mode; - int ret1, ret2; - aiColor4D diffuse; - aiColor4D specular; - aiColor4D ambient; - aiColor4D emission; - float shininess, strength; - int two_sided; - int wireframe; - unsigned int max; // changed: to unsigned - - int texIndex = 0; - aiString texPath; //contains filename of texture - - if(AI_SUCCESS == mtl->GetTexture(aiTextureType_DIFFUSE, texIndex, &texPath)) - { - //bind texture - unsigned int texId = *textureIdMap[texPath.data]; - glBindTexture(GL_TEXTURE_2D, texId); - } - - set_float4(c, 0.8f, 0.8f, 0.8f, 1.0f); - if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_DIFFUSE, &diffuse)) - color4_to_float4(&diffuse, c); - glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, c); - - set_float4(c, 0.0f, 0.0f, 0.0f, 1.0f); - if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_SPECULAR, &specular)) - color4_to_float4(&specular, c); - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, c); - - set_float4(c, 0.2f, 0.2f, 0.2f, 1.0f); - if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_AMBIENT, &ambient)) - color4_to_float4(&ambient, c); - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, c); - - set_float4(c, 0.0f, 0.0f, 0.0f, 1.0f); - if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_EMISSIVE, &emission)) - color4_to_float4(&emission, c); - glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, c); - - max = 1; - ret1 = aiGetMaterialFloatArray(mtl, AI_MATKEY_SHININESS, &shininess, &max); - max = 1; - ret2 = aiGetMaterialFloatArray(mtl, AI_MATKEY_SHININESS_STRENGTH, &strength, &max); - if((ret1 == AI_SUCCESS) && (ret2 == AI_SUCCESS)) - glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess * strength); - else { - glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0f); - set_float4(c, 0.0f, 0.0f, 0.0f, 0.0f); - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, c); - } - - max = 1; - if(AI_SUCCESS == aiGetMaterialIntegerArray(mtl, AI_MATKEY_ENABLE_WIREFRAME, &wireframe, &max)) - fill_mode = wireframe ? GL_LINE : GL_FILL; - else - fill_mode = GL_FILL; - glPolygonMode(GL_FRONT_AND_BACK, fill_mode); - - max = 1; - if((AI_SUCCESS == aiGetMaterialIntegerArray(mtl, AI_MATKEY_TWOSIDED, &two_sided, &max)) && two_sided) - glEnable(GL_CULL_FACE); - else - glDisable(GL_CULL_FACE); -} - - -void recursive_render (const struct aiScene *sc, const struct aiNode* nd, float scale) -{ - unsigned int i; - unsigned int n=0, t; - aiMatrix4x4 m = nd->mTransformation; - - aiMatrix4x4 m2; - aiMatrix4x4::Scaling(aiVector3D(scale, scale, scale), m2); - m = m * m2; - - // update transform - m.Transpose(); - glPushMatrix(); - glMultMatrixf((float*)&m); - - // draw all meshes assigned to this node - for (; n < nd->mNumMeshes; ++n) - { - const struct aiMesh* mesh = scene->mMeshes[nd->mMeshes[n]]; - - apply_material(sc->mMaterials[mesh->mMaterialIndex]); - - - if(mesh->mNormals == NULL) - { - glDisable(GL_LIGHTING); - } - else - { - glEnable(GL_LIGHTING); - } - - if(mesh->mColors[0] != NULL) - { - glEnable(GL_COLOR_MATERIAL); - } - else - { - glDisable(GL_COLOR_MATERIAL); - } - - for (t = 0; t < mesh->mNumFaces; ++t) { - const struct aiFace* face = &mesh->mFaces[t]; - GLenum face_mode; - - switch(face->mNumIndices) - { - case 1: face_mode = GL_POINTS; break; - case 2: face_mode = GL_LINES; break; - case 3: face_mode = GL_TRIANGLES; break; - default: face_mode = GL_POLYGON; break; - } - - glBegin(face_mode); - - for(i = 0; i < face->mNumIndices; i++) // go through all vertices in face - { - int vertexIndex = face->mIndices[i]; // get group index for current index - if(mesh->mColors[0] != NULL) - Color4f(&mesh->mColors[0][vertexIndex]); - if(mesh->mNormals != NULL) - - if(mesh->HasTextureCoords(0)) //HasTextureCoords(texture_coordinates_set) - { - glTexCoord2f(mesh->mTextureCoords[0][vertexIndex].x, 1 - mesh->mTextureCoords[0][vertexIndex].y); //mTextureCoords[channel][vertex] - } - - glNormal3fv(&mesh->mNormals[vertexIndex].x); - glVertex3fv(&mesh->mVertices[vertexIndex].x); - } - glEnd(); - } - } - - // draw all children - for (n = 0; n < nd->mNumChildren; ++n) - { - recursive_render(sc, nd->mChildren[n], scale); - } - - glPopMatrix(); -} - - -void drawAiScene(const aiScene* scene) -{ - logInfo("drawing objects"); - - recursive_render(scene, scene->mRootNode, 0.5); - -} - -int DrawGLScene() //Here's where we do all the drawing -{ - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer - glLoadIdentity(); // Reset MV Matrix - - - glTranslatef(0.0f, -10.0f, -40.0f); // Move 40 Units And Into The Screen - - - glRotatef(xrot, 1.0f, 0.0f, 0.0f); - glRotatef(yrot, 0.0f, 1.0f, 0.0f); - glRotatef(zrot, 0.0f, 0.0f, 1.0f); - - drawAiScene(scene); - - //xrot+=0.3f; - yrot+=0.2f; - //zrot+=0.4f; - - return TRUE; // okay -} - - -void KillGLWindow() // Properly Kill The Window -{ - if (fullscreen) // Are We In Fullscreen Mode? - { - ChangeDisplaySettings(NULL, 0); // If So Switch Back To The Desktop - ShowCursor(TRUE); // Show Mouse Pointer - } - - if (hRC) // Do We Have A Rendering Context? - { - if (!wglMakeCurrent(NULL, NULL)) // Are We Able To Release The DC And RC Contexts? - { - MessageBox(NULL, "Release Of DC And RC Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); - } - - if (!wglDeleteContext(hRC)) // Are We Able To Delete The RC? - { - MessageBox(NULL, "Release Rendering Context Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); - } - hRC = NULL; - } - - if (hDC && !ReleaseDC(hWnd, hDC)) // Are We able to Release The DC? - { - MessageBox(NULL, "Release Device Context Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); - hDC=NULL; - } - - if (hWnd && !DestroyWindow(hWnd)) // Are We Able To Destroy The Window - { - MessageBox(NULL, "Could Not Release hWnd.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); - hWnd = NULL; - } - - if (!UnregisterClass("OpenGL", hInstance)) // Are We Able To Unregister Class - { - MessageBox(NULL, "Could Not Unregister Class.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); - hInstance = NULL; - } -} - -GLboolean abortGLInit(const char* abortMessage) -{ - KillGLWindow(); // Reset Display - MessageBox(NULL, abortMessage, "ERROR", MB_OK|MB_ICONEXCLAMATION); - return FALSE; // quit and return False -} - -BOOL CreateGLWindow(const char* title, int width, int height, int bits, bool fullscreenflag) -{ - GLuint PixelFormat; // Hold the result after searching for a match - WNDCLASS wc; // Window Class Structure - DWORD dwExStyle; // Window Extended Style - DWORD dwStyle; // Window Style - RECT WindowRect; // Grabs Rectangle Upper Left / Lower Right Values - WindowRect.left = (long)0; - WindowRect.right = (long)width; - WindowRect.top = (long)0; - WindowRect.bottom = (long)height; - - fullscreen = fullscreenflag; - - hInstance = GetModuleHandle(NULL); // Grab An Instance For Our Window - wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw On Move, And Own DC For Window - wc.lpfnWndProc = (WNDPROC) WndProc; // WndProc handles Messages - wc.cbClsExtra = 0; // No Extra Window Data - wc.cbWndExtra = 0; // No Extra Window Data - wc.hInstance = hInstance; - wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); // Load The Default Icon - wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Load the default arrow - wc.hbrBackground= NULL; // No Background required for OpenGL - wc.lpszMenuName = NULL; // No Menu - wc.lpszClassName= "OpenGL"; // Class Name - - if (!RegisterClass(&wc)) - { - MessageBox(NULL, "Failed to register the window class", "ERROR", MB_OK | MB_ICONEXCLAMATION); - return FALSE; //exit and return false - } - - if (fullscreen) // attempt fullscreen mode - { - DEVMODE dmScreenSettings; // Device Mode - memset(&dmScreenSettings, 0, sizeof(dmScreenSettings)); // Make Sure Memory's Cleared - dmScreenSettings.dmSize = sizeof(dmScreenSettings); // Size Of the devmode structure - dmScreenSettings.dmPelsWidth = width; // Selected Screen Width - dmScreenSettings.dmPelsHeight = height; // Selected Screen Height - dmScreenSettings.dmBitsPerPel = bits; // bits per pixel - dmScreenSettings.dmFields = DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT; - - // Try To Set Selected Mode and Get Results. NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar. - if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL) - { - // If The Mode Fails, Offer Two Options. Quit Or Run In A Window. - if (MessageBox(NULL,"The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?","NeHe GL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES) - { - fullscreen = FALSE; // Select Windowed Mode (Fullscreen = FALSE) - } - else - { - //Popup Messagebox: Closing - MessageBox(NULL, "Program will close now.", "ERROR", MB_OK|MB_ICONSTOP); - return FALSE; //exit, return false - } - } - } - - if (fullscreen) // when mode really succeeded - { - dwExStyle=WS_EX_APPWINDOW; // Window Extended Style - dwStyle=WS_POPUP; - ShowCursor(FALSE); - } - else - { - dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Window extended style - dwStyle=WS_OVERLAPPEDWINDOW; // Windows style - } - - AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); // Adjust Window To True Requestes Size - - if (!(hWnd=CreateWindowEx( dwExStyle, // Extended Style For The Window - "OpenGL", // Class Name - title, // Window Title - WS_CLIPSIBLINGS | // Required Window Style - WS_CLIPCHILDREN | // Required Window Style - dwStyle, // Selected WIndow Style - 0, 0, // Window Position - WindowRect.right-WindowRect.left, // Calc adjusted Window Width - WindowRect.bottom-WindowRect.top, // Calc adjustes Window Height - NULL, // No Parent Window - NULL, // No Menu - hInstance, // Instance - NULL ))) // Don't pass anything To WM_CREATE - { - abortGLInit("Window Creation Error."); - return FALSE; - } - - static PIXELFORMATDESCRIPTOR pfd= // pfd Tells Windows How We Want Things To Be - { - sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor - 1, // Version Number - PFD_DRAW_TO_WINDOW | // Format Must Support Window - PFD_SUPPORT_OPENGL | // Format Must Support OpenGL - PFD_DOUBLEBUFFER, // Must Support Double Buffering - PFD_TYPE_RGBA, // Request An RGBA Format - bits, // Select Our Color Depth - 0, 0, 0, 0, 0, 0, // Color Bits Ignored - 0, // No Alpha Buffer - 0, // Shift Bit Ignored - 0, // No Accumulation Buffer - 0, 0, 0, 0, // Accumulation Bits Ignored - 16, // 16Bit Z-Buffer (Depth Buffer) - 0, // No Stencil Buffer - 0, // No Auxiliary Buffer - PFD_MAIN_PLANE, // Main Drawing Layer - 0, // Reserved - 0, 0, 0 // Layer Masks Ignored - }; - - if (!(hDC=GetDC(hWnd))) // Did we get the Device Context? - { - abortGLInit("Can't Create A GL Device Context."); - return FALSE; - } - - if (!(PixelFormat=ChoosePixelFormat(hDC, &pfd))) // Did We Find a matching pixel Format? - { - abortGLInit("Can't Find Suitable PixelFormat"); - return FALSE; - } - - if (!SetPixelFormat(hDC, PixelFormat, &pfd)) - { - abortGLInit("Can't Set The PixelFormat"); - return FALSE; - } - - if (!(hRC=wglCreateContext(hDC))) - { - abortGLInit("Can't Create A GL Rendering Context."); - return FALSE; - } - - if (!(wglMakeCurrent(hDC,hRC))) // Try to activate the rendering context - { - abortGLInit("Can't Activate The Rendering Context"); - return FALSE; - } - - //// *** everything okay *** - - ShowWindow(hWnd, SW_SHOW); // Show The Window - SetForegroundWindow(hWnd); // Slightly Higher Prio - SetFocus(hWnd); // Sets Keyboard Focus To The Window - ReSizeGLScene(width, height); // Set Up Our Perspective GL Screen - - if (!InitGL()) - { - abortGLInit("Initialization failed"); - return FALSE; - } - - return TRUE; -} - -LRESULT CALLBACK WndProc(HWND hWnd, // Handles for this Window - UINT uMsg, // Message for this Window - WPARAM wParam, // additional message Info - LPARAM lParam) // additional message Info -{ - switch (uMsg) // check for Window Messages - { - case WM_ACTIVATE: // Watch For Window Activate Message - { - if (!HIWORD(wParam)) // Check Minimization State - { - active=TRUE; - } - else - { - active=FALSE; - } - - return 0; // return To The Message Loop - } - - case WM_SYSCOMMAND: // Interrupt System Commands - { - switch (wParam) - { - case SC_SCREENSAVE: // Screen-saver trying to start - case SC_MONITORPOWER: // Monitor trying to enter power-safe - return 0; - } - break; - } - - case WM_CLOSE: // close message received? - { - PostQuitMessage(0); // Send WM_QUIT quit message - return 0; // Jump Back - } - - case WM_KEYDOWN: // Is a key pressed? - { - keys[wParam] = TRUE; // If so, Mark it as true - return 0; - } - - case WM_KEYUP: // Has Key Been released? - { - keys[wParam] = FALSE; // If so, Mark It As FALSE - return 0; - } - - case WM_SIZE: // Resize The OpenGL Window - { - ReSizeGLScene(LOWORD(lParam), HIWORD(lParam)); // LoWord-Width, HiWord-Height - return 0; - } - } - - // Pass All unhandled Messaged To DefWindowProc - return DefWindowProc(hWnd, uMsg, wParam, lParam); -} - -int WINAPI WinMain( HINSTANCE hInstance, // The instance - HINSTANCE hPrevInstance, // Previous instance - LPSTR lpCmdLine, // Command Line Parameters - int nShowCmd ) // Window Show State -{ - MSG msg; - BOOL done=FALSE; - - createAILogger(); - logInfo("App fired!"); - - // Check the command line for an override file path. - int argc; - LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc); - if (argv != NULL && argc > 1) - { - std::wstring modelpathW(argv[1]); - modelpath = std::string(modelpathW.begin(), modelpathW.end()); - } - - if (!Import3DFromFile(modelpath)) return 0; - - logInfo("=============== Post Import ===================="); - - if (MessageBox(NULL, "Would You Like To Run In Fullscreen Mode?", "Start Fullscreen?", MB_YESNO|MB_ICONEXCLAMATION)==IDNO) - { - fullscreen=FALSE; - } - - if (!CreateGLWindow(windowTitle, 640, 480, 16, fullscreen)) - { - return 0; - } - - while(!done) // Game Loop - { - if (PeekMessage(&msg, NULL, 0,0, PM_REMOVE)) - { - if (msg.message==WM_QUIT) - { - done=TRUE; - } - else - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - else - { - // Draw The Scene. Watch For ESC Key And Quit Messaged From DrawGLScene() - if (active) - { - if (keys[VK_ESCAPE]) - { - done=TRUE; - } - else - { - DrawGLScene(); - SwapBuffers(hDC); - } - } - - if (keys[VK_F1]) - { - keys[VK_F1]=FALSE; - KillGLWindow(); - fullscreen=!fullscreen; - if (!CreateGLWindow(windowTitle, 640, 480, 16, fullscreen)) - { - return 0; - } - } - } - } - - // *** cleanup *** - - textureIdMap.clear(); //no need to delete pointers in it manually here. (Pointers point to textureIds deleted in next step) - - if (textureIds) - { - delete[] textureIds; - textureIds = NULL; - } - - // *** cleanup end *** - - destroyAILogger(); - KillGLWindow(); - return (msg.wParam); -} +// ---------------------------------------------------------------------------- +// Another Assimp OpenGL sample including texturing. +// Note that it is very basic and will only read and apply the model's diffuse +// textures (by their material ids) +// +// Don't worry about the "Couldn't load Image: ...dwarf2.jpg" Message. +// It's caused by a bad texture reference in the model file (I guess) +// +// If you intend to _use_ this code sample in your app, do yourself a favour +// and replace immediate mode calls with VBOs ... +// +// Thanks to NeHe on whose OpenGL tutorials this one's based on! :) +// http://nehe.gamedev.net/ +// ---------------------------------------------------------------------------- +#include +#include +#include +#include +#include + +#include + +//to map image filenames to textureIds +#include +#include + + +// assimp include files. These three are usually needed. +#include "assimp/Importer.hpp" //OO version Header! +#include "assimp/postprocess.h" +#include "assimp/scene.h" +#include "assimp/DefaultLogger.hpp" +#include "assimp/LogStream.hpp" + + +// The default hard-coded path. Can be overridden by supplying a path through the command line. +static std::string modelpath = "../../test/models/OBJ/spider.obj"; + + +HGLRC hRC=NULL; // Permanent Rendering Context +HDC hDC=NULL; // Private GDI Device Context +HWND hWnd=NULL; // Holds Window Handle +HINSTANCE hInstance; // Holds The Instance Of The Application + +bool keys[256]; // Array used for Keyboard Routine; +bool active=TRUE; // Window Active Flag Set To TRUE by Default +bool fullscreen=TRUE; // full-screen Flag Set To full-screen By Default + +GLfloat xrot; +GLfloat yrot; +GLfloat zrot; + + +LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration For WndProc +GLboolean abortGLInit(const char*); + +const char* windowTitle = "OpenGL Framework"; + +GLfloat LightAmbient[]= { 0.5f, 0.5f, 0.5f, 1.0f }; +GLfloat LightDiffuse[]= { 1.0f, 1.0f, 1.0f, 1.0f }; +GLfloat LightPosition[]= { 0.0f, 0.0f, 15.0f, 1.0f }; + + + +// the global Assimp scene object +const aiScene* scene = NULL; +GLuint scene_list = 0; +aiVector3D scene_min, scene_max, scene_center; + +// images / texture +std::map textureIdMap; // map image filenames to textureIds +GLuint* textureIds; // pointer to texture Array + +// Create an instance of the Importer class +Assimp::Importer importer; + + +void createAILogger() +{ + // Change this line to normal if you not want to analyse the import process + //Assimp::Logger::LogSeverity severity = Assimp::Logger::NORMAL; + Assimp::Logger::LogSeverity severity = Assimp::Logger::VERBOSE; + + // Create a logger instance for Console Output + Assimp::DefaultLogger::create("",severity, aiDefaultLogStream_STDOUT); + + // Create a logger instance for File Output (found in project folder or near .exe) + Assimp::DefaultLogger::create("assimp_log.txt",severity, aiDefaultLogStream_FILE); + + // Now I am ready for logging my stuff + Assimp::DefaultLogger::get()->info("this is my info-call"); +} + +void destroyAILogger() +{ + // Kill it after the work is done + Assimp::DefaultLogger::kill(); +} + +void logInfo(std::string logString) +{ + // Will add message to File with "info" Tag + Assimp::DefaultLogger::get()->info(logString.c_str()); +} + +void logDebug(const char* logString) +{ + // Will add message to File with "debug" Tag + Assimp::DefaultLogger::get()->debug(logString); +} + + +bool Import3DFromFile( const std::string& pFile) +{ + // Check if file exists + std::ifstream fin(pFile.c_str()); + if(!fin.fail()) + { + fin.close(); + } + else + { + MessageBox(NULL, ("Couldn't open file: " + pFile).c_str() , "ERROR", MB_OK | MB_ICONEXCLAMATION); + logInfo( importer.GetErrorString()); + return false; + } + + scene = importer.ReadFile( pFile, aiProcessPreset_TargetRealtime_Quality); + + // If the import failed, report it + if( !scene) + { + logInfo( importer.GetErrorString()); + return false; + } + + // Now we can access the file's contents. + logInfo("Import of scene " + pFile + " succeeded."); + + // We're done. Everything will be cleaned up by the importer destructor + return true; +} + +// Resize And Initialize The GL Window +void ReSizeGLScene(GLsizei width, GLsizei height) +{ + // Prevent A Divide By Zero By + if (height==0) + { + // Making Height Equal One + height=1; + } + + glViewport(0, 0, width, height); // Reset The Current Viewport + + glMatrixMode(GL_PROJECTION); // Select The Projection Matrix + glLoadIdentity(); // Reset The Projection Matrix + + // Calculate The Aspect Ratio Of The Window + gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f); + + glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix + glLoadIdentity(); // Reset The Modelview Matrix +} + + +std::string getBasePath(const std::string& path) +{ + size_t pos = path.find_last_of("\\/"); + return (std::string::npos == pos) ? "" : path.substr(0, pos + 1); +} + +int LoadGLTextures(const aiScene* scene) +{ + ILboolean success; + + /* Before calling ilInit() version should be checked. */ + if (ilGetInteger(IL_VERSION_NUM) < IL_VERSION) + { + /// wrong DevIL version /// + std::string err_msg = "Wrong DevIL version. Old devil.dll in system32/SysWow64?"; + char* cErr_msg = (char *) err_msg.c_str(); + abortGLInit(cErr_msg); + return -1; + } + + ilInit(); /* Initialization of DevIL */ + + if (scene->HasTextures()) abortGLInit("Support for meshes with embedded textures is not implemented"); + + /* getTexture Filenames and Numb of Textures */ + for (unsigned int m=0; mmNumMaterials; m++) + { + int texIndex = 0; + aiReturn texFound = AI_SUCCESS; + + aiString path; // filename + + while (texFound == AI_SUCCESS) + { + texFound = scene->mMaterials[m]->GetTexture(aiTextureType_DIFFUSE, texIndex, &path); + textureIdMap[path.data] = NULL; //fill map with textures, pointers still NULL yet + texIndex++; + } + } + + int numTextures = textureIdMap.size(); + + /* array with DevIL image IDs */ + ILuint* imageIds = NULL; + imageIds = new ILuint[numTextures]; + + /* generate DevIL Image IDs */ + ilGenImages(numTextures, imageIds); /* Generation of numTextures image names */ + + /* create and fill array with GL texture ids */ + textureIds = new GLuint[numTextures]; + glGenTextures(numTextures, textureIds); /* Texture name generation */ + + /* get iterator */ + std::map::iterator itr = textureIdMap.begin(); + + std::string basepath = getBasePath(modelpath); + for (int i=0; ir, color->g, color->b, color->a); +} + +void set_float4(float f[4], float a, float b, float c, float d) +{ + f[0] = a; + f[1] = b; + f[2] = c; + f[3] = d; +} + +void color4_to_float4(const aiColor4D *c, float f[4]) +{ + f[0] = c->r; + f[1] = c->g; + f[2] = c->b; + f[3] = c->a; +} + +void apply_material(const aiMaterial *mtl) +{ + float c[4]; + + GLenum fill_mode; + int ret1, ret2; + aiColor4D diffuse; + aiColor4D specular; + aiColor4D ambient; + aiColor4D emission; + float shininess, strength; + int two_sided; + int wireframe; + unsigned int max; // changed: to unsigned + + int texIndex = 0; + aiString texPath; //contains filename of texture + + if(AI_SUCCESS == mtl->GetTexture(aiTextureType_DIFFUSE, texIndex, &texPath)) + { + //bind texture + unsigned int texId = *textureIdMap[texPath.data]; + glBindTexture(GL_TEXTURE_2D, texId); + } + + set_float4(c, 0.8f, 0.8f, 0.8f, 1.0f); + if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_DIFFUSE, &diffuse)) + color4_to_float4(&diffuse, c); + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, c); + + set_float4(c, 0.0f, 0.0f, 0.0f, 1.0f); + if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_SPECULAR, &specular)) + color4_to_float4(&specular, c); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, c); + + set_float4(c, 0.2f, 0.2f, 0.2f, 1.0f); + if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_AMBIENT, &ambient)) + color4_to_float4(&ambient, c); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, c); + + set_float4(c, 0.0f, 0.0f, 0.0f, 1.0f); + if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_EMISSIVE, &emission)) + color4_to_float4(&emission, c); + glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, c); + + max = 1; + ret1 = aiGetMaterialFloatArray(mtl, AI_MATKEY_SHININESS, &shininess, &max); + max = 1; + ret2 = aiGetMaterialFloatArray(mtl, AI_MATKEY_SHININESS_STRENGTH, &strength, &max); + if((ret1 == AI_SUCCESS) && (ret2 == AI_SUCCESS)) + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess * strength); + else { + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0f); + set_float4(c, 0.0f, 0.0f, 0.0f, 0.0f); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, c); + } + + max = 1; + if(AI_SUCCESS == aiGetMaterialIntegerArray(mtl, AI_MATKEY_ENABLE_WIREFRAME, &wireframe, &max)) + fill_mode = wireframe ? GL_LINE : GL_FILL; + else + fill_mode = GL_FILL; + glPolygonMode(GL_FRONT_AND_BACK, fill_mode); + + max = 1; + if((AI_SUCCESS == aiGetMaterialIntegerArray(mtl, AI_MATKEY_TWOSIDED, &two_sided, &max)) && two_sided) + glEnable(GL_CULL_FACE); + else + glDisable(GL_CULL_FACE); +} + + +void recursive_render (const struct aiScene *sc, const struct aiNode* nd, float scale) +{ + unsigned int i; + unsigned int n=0, t; + aiMatrix4x4 m = nd->mTransformation; + + aiMatrix4x4 m2; + aiMatrix4x4::Scaling(aiVector3D(scale, scale, scale), m2); + m = m * m2; + + // update transform + m.Transpose(); + glPushMatrix(); + glMultMatrixf((float*)&m); + + // draw all meshes assigned to this node + for (; n < nd->mNumMeshes; ++n) + { + const struct aiMesh* mesh = scene->mMeshes[nd->mMeshes[n]]; + + apply_material(sc->mMaterials[mesh->mMaterialIndex]); + + + if(mesh->mNormals == NULL) + { + glDisable(GL_LIGHTING); + } + else + { + glEnable(GL_LIGHTING); + } + + if(mesh->mColors[0] != NULL) + { + glEnable(GL_COLOR_MATERIAL); + } + else + { + glDisable(GL_COLOR_MATERIAL); + } + + for (t = 0; t < mesh->mNumFaces; ++t) { + const struct aiFace* face = &mesh->mFaces[t]; + GLenum face_mode; + + switch(face->mNumIndices) + { + case 1: face_mode = GL_POINTS; break; + case 2: face_mode = GL_LINES; break; + case 3: face_mode = GL_TRIANGLES; break; + default: face_mode = GL_POLYGON; break; + } + + glBegin(face_mode); + + for(i = 0; i < face->mNumIndices; i++) // go through all vertices in face + { + int vertexIndex = face->mIndices[i]; // get group index for current index + if(mesh->mColors[0] != NULL) + Color4f(&mesh->mColors[0][vertexIndex]); + if(mesh->mNormals != NULL) + + if(mesh->HasTextureCoords(0)) //HasTextureCoords(texture_coordinates_set) + { + glTexCoord2f(mesh->mTextureCoords[0][vertexIndex].x, 1 - mesh->mTextureCoords[0][vertexIndex].y); //mTextureCoords[channel][vertex] + } + + glNormal3fv(&mesh->mNormals[vertexIndex].x); + glVertex3fv(&mesh->mVertices[vertexIndex].x); + } + glEnd(); + } + } + + // draw all children + for (n = 0; n < nd->mNumChildren; ++n) + { + recursive_render(sc, nd->mChildren[n], scale); + } + + glPopMatrix(); +} + + +void drawAiScene(const aiScene* scene) +{ + logInfo("drawing objects"); + + recursive_render(scene, scene->mRootNode, 0.5); + +} + +int DrawGLScene() //Here's where we do all the drawing +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer + glLoadIdentity(); // Reset MV Matrix + + + glTranslatef(0.0f, -10.0f, -40.0f); // Move 40 Units And Into The Screen + + + glRotatef(xrot, 1.0f, 0.0f, 0.0f); + glRotatef(yrot, 0.0f, 1.0f, 0.0f); + glRotatef(zrot, 0.0f, 0.0f, 1.0f); + + drawAiScene(scene); + + //xrot+=0.3f; + yrot+=0.2f; + //zrot+=0.4f; + + return TRUE; // okay +} + + +void KillGLWindow() // Properly Kill The Window +{ + if (fullscreen) // Are We In Fullscreen Mode? + { + ChangeDisplaySettings(NULL, 0); // If So Switch Back To The Desktop + ShowCursor(TRUE); // Show Mouse Pointer + } + + if (hRC) // Do We Have A Rendering Context? + { + if (!wglMakeCurrent(NULL, NULL)) // Are We Able To Release The DC And RC Contexts? + { + MessageBox(NULL, "Release Of DC And RC Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); + } + + if (!wglDeleteContext(hRC)) // Are We Able To Delete The RC? + { + MessageBox(NULL, "Release Rendering Context Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); + } + hRC = NULL; + } + + if (hDC && !ReleaseDC(hWnd, hDC)) // Are We able to Release The DC? + { + MessageBox(NULL, "Release Device Context Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); + hDC=NULL; + } + + if (hWnd && !DestroyWindow(hWnd)) // Are We Able To Destroy The Window + { + MessageBox(NULL, "Could Not Release hWnd.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); + hWnd = NULL; + } + + if (!UnregisterClass("OpenGL", hInstance)) // Are We Able To Unregister Class + { + MessageBox(NULL, "Could Not Unregister Class.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); + hInstance = NULL; + } +} + +GLboolean abortGLInit(const char* abortMessage) +{ + KillGLWindow(); // Reset Display + MessageBox(NULL, abortMessage, "ERROR", MB_OK|MB_ICONEXCLAMATION); + return FALSE; // quit and return False +} + +BOOL CreateGLWindow(const char* title, int width, int height, int bits, bool fullscreenflag) +{ + GLuint PixelFormat; // Hold the result after searching for a match + WNDCLASS wc; // Window Class Structure + DWORD dwExStyle; // Window Extended Style + DWORD dwStyle; // Window Style + RECT WindowRect; // Grabs Rectangle Upper Left / Lower Right Values + WindowRect.left = (long)0; + WindowRect.right = (long)width; + WindowRect.top = (long)0; + WindowRect.bottom = (long)height; + + fullscreen = fullscreenflag; + + hInstance = GetModuleHandle(NULL); // Grab An Instance For Our Window + wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw On Move, And Own DC For Window + wc.lpfnWndProc = (WNDPROC) WndProc; // WndProc handles Messages + wc.cbClsExtra = 0; // No Extra Window Data + wc.cbWndExtra = 0; // No Extra Window Data + wc.hInstance = hInstance; + wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); // Load The Default Icon + wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Load the default arrow + wc.hbrBackground= NULL; // No Background required for OpenGL + wc.lpszMenuName = NULL; // No Menu + wc.lpszClassName= "OpenGL"; // Class Name + + if (!RegisterClass(&wc)) + { + MessageBox(NULL, "Failed to register the window class", "ERROR", MB_OK | MB_ICONEXCLAMATION); + return FALSE; //exit and return false + } + + if (fullscreen) // attempt fullscreen mode + { + DEVMODE dmScreenSettings; // Device Mode + memset(&dmScreenSettings, 0, sizeof(dmScreenSettings)); // Make Sure Memory's Cleared + dmScreenSettings.dmSize = sizeof(dmScreenSettings); // Size Of the devmode structure + dmScreenSettings.dmPelsWidth = width; // Selected Screen Width + dmScreenSettings.dmPelsHeight = height; // Selected Screen Height + dmScreenSettings.dmBitsPerPel = bits; // bits per pixel + dmScreenSettings.dmFields = DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT; + + // Try To Set Selected Mode and Get Results. NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar. + if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL) + { + // If The Mode Fails, Offer Two Options. Quit Or Run In A Window. + if (MessageBox(NULL,"The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?","NeHe GL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES) + { + fullscreen = FALSE; // Select Windowed Mode (Fullscreen = FALSE) + } + else + { + //Popup Messagebox: Closing + MessageBox(NULL, "Program will close now.", "ERROR", MB_OK|MB_ICONSTOP); + return FALSE; //exit, return false + } + } + } + + if (fullscreen) // when mode really succeeded + { + dwExStyle=WS_EX_APPWINDOW; // Window Extended Style + dwStyle=WS_POPUP; + ShowCursor(FALSE); + } + else + { + dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Window extended style + dwStyle=WS_OVERLAPPEDWINDOW; // Windows style + } + + AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); // Adjust Window To True Requestes Size + + if (!(hWnd=CreateWindowEx( dwExStyle, // Extended Style For The Window + "OpenGL", // Class Name + title, // Window Title + WS_CLIPSIBLINGS | // Required Window Style + WS_CLIPCHILDREN | // Required Window Style + dwStyle, // Selected WIndow Style + 0, 0, // Window Position + WindowRect.right-WindowRect.left, // Calc adjusted Window Width + WindowRect.bottom-WindowRect.top, // Calc adjustes Window Height + NULL, // No Parent Window + NULL, // No Menu + hInstance, // Instance + NULL ))) // Don't pass anything To WM_CREATE + { + abortGLInit("Window Creation Error."); + return FALSE; + } + + static PIXELFORMATDESCRIPTOR pfd= // pfd Tells Windows How We Want Things To Be + { + sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor + 1, // Version Number + PFD_DRAW_TO_WINDOW | // Format Must Support Window + PFD_SUPPORT_OPENGL | // Format Must Support OpenGL + PFD_DOUBLEBUFFER, // Must Support Double Buffering + PFD_TYPE_RGBA, // Request An RGBA Format + bits, // Select Our Color Depth + 0, 0, 0, 0, 0, 0, // Color Bits Ignored + 0, // No Alpha Buffer + 0, // Shift Bit Ignored + 0, // No Accumulation Buffer + 0, 0, 0, 0, // Accumulation Bits Ignored + 16, // 16Bit Z-Buffer (Depth Buffer) + 0, // No Stencil Buffer + 0, // No Auxiliary Buffer + PFD_MAIN_PLANE, // Main Drawing Layer + 0, // Reserved + 0, 0, 0 // Layer Masks Ignored + }; + + if (!(hDC=GetDC(hWnd))) // Did we get the Device Context? + { + abortGLInit("Can't Create A GL Device Context."); + return FALSE; + } + + if (!(PixelFormat=ChoosePixelFormat(hDC, &pfd))) // Did We Find a matching pixel Format? + { + abortGLInit("Can't Find Suitable PixelFormat"); + return FALSE; + } + + if (!SetPixelFormat(hDC, PixelFormat, &pfd)) + { + abortGLInit("Can't Set The PixelFormat"); + return FALSE; + } + + if (!(hRC=wglCreateContext(hDC))) + { + abortGLInit("Can't Create A GL Rendering Context."); + return FALSE; + } + + if (!(wglMakeCurrent(hDC,hRC))) // Try to activate the rendering context + { + abortGLInit("Can't Activate The Rendering Context"); + return FALSE; + } + + //// *** everything okay *** + + ShowWindow(hWnd, SW_SHOW); // Show The Window + SetForegroundWindow(hWnd); // Slightly Higher Prio + SetFocus(hWnd); // Sets Keyboard Focus To The Window + ReSizeGLScene(width, height); // Set Up Our Perspective GL Screen + + if (!InitGL()) + { + abortGLInit("Initialization failed"); + return FALSE; + } + + return TRUE; +} + +LRESULT CALLBACK WndProc(HWND hWnd, // Handles for this Window + UINT uMsg, // Message for this Window + WPARAM wParam, // additional message Info + LPARAM lParam) // additional message Info +{ + switch (uMsg) // check for Window Messages + { + case WM_ACTIVATE: // Watch For Window Activate Message + { + if (!HIWORD(wParam)) // Check Minimization State + { + active=TRUE; + } + else + { + active=FALSE; + } + + return 0; // return To The Message Loop + } + + case WM_SYSCOMMAND: // Interrupt System Commands + { + switch (wParam) + { + case SC_SCREENSAVE: // Screen-saver trying to start + case SC_MONITORPOWER: // Monitor trying to enter power-safe + return 0; + } + break; + } + + case WM_CLOSE: // close message received? + { + PostQuitMessage(0); // Send WM_QUIT quit message + return 0; // Jump Back + } + + case WM_KEYDOWN: // Is a key pressed? + { + keys[wParam] = TRUE; // If so, Mark it as true + return 0; + } + + case WM_KEYUP: // Has Key Been released? + { + keys[wParam] = FALSE; // If so, Mark It As FALSE + return 0; + } + + case WM_SIZE: // Resize The OpenGL Window + { + ReSizeGLScene(LOWORD(lParam), HIWORD(lParam)); // LoWord-Width, HiWord-Height + return 0; + } + } + + // Pass All unhandled Messaged To DefWindowProc + return DefWindowProc(hWnd, uMsg, wParam, lParam); +} + +int WINAPI WinMain( HINSTANCE hInstance, // The instance + HINSTANCE hPrevInstance, // Previous instance + LPSTR lpCmdLine, // Command Line Parameters + int nShowCmd ) // Window Show State +{ + MSG msg; + BOOL done=FALSE; + + createAILogger(); + logInfo("App fired!"); + + // Check the command line for an override file path. + int argc; + LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc); + if (argv != NULL && argc > 1) + { + std::wstring modelpathW(argv[1]); + modelpath = std::string(modelpathW.begin(), modelpathW.end()); + } + + if (!Import3DFromFile(modelpath)) return 0; + + logInfo("=============== Post Import ===================="); + + if (MessageBox(NULL, "Would You Like To Run In Fullscreen Mode?", "Start Fullscreen?", MB_YESNO|MB_ICONEXCLAMATION)==IDNO) + { + fullscreen=FALSE; + } + + if (!CreateGLWindow(windowTitle, 640, 480, 16, fullscreen)) + { + return 0; + } + + while(!done) // Game Loop + { + if (PeekMessage(&msg, NULL, 0,0, PM_REMOVE)) + { + if (msg.message==WM_QUIT) + { + done=TRUE; + } + else + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + else + { + // Draw The Scene. Watch For ESC Key And Quit Messaged From DrawGLScene() + if (active) + { + if (keys[VK_ESCAPE]) + { + done=TRUE; + } + else + { + DrawGLScene(); + SwapBuffers(hDC); + } + } + + if (keys[VK_F1]) + { + keys[VK_F1]=FALSE; + KillGLWindow(); + fullscreen=!fullscreen; + if (!CreateGLWindow(windowTitle, 640, 480, 16, fullscreen)) + { + return 0; + } + } + } + } + + // *** cleanup *** + + textureIdMap.clear(); //no need to delete pointers in it manually here. (Pointers point to textureIds deleted in next step) + + if (textureIds) + { + delete[] textureIds; + textureIds = NULL; + } + + // *** cleanup end *** + + destroyAILogger(); + KillGLWindow(); + return (msg.wParam); +} diff --git a/samples/glut/GL/glut.h b/samples/glut/GL/glut.h index aa7428f36..0e6ddfbfe 100644 --- a/samples/glut/GL/glut.h +++ b/samples/glut/GL/glut.h @@ -1,716 +1,716 @@ -#ifndef __glut_h__ -#define __glut_h__ - -/* Copyright (c) Mark J. Kilgard, 1994, 1995, 1996, 1998. */ - -/* This program is freely distributable without licensing fees and is - provided without guarantee or warrantee expressed or implied. This - program is -not- in the public domain. */ - -#if defined(_WIN32) - -/* GLUT 3.7 now tries to avoid including - to avoid name space pollution, but Win32's - needs APIENTRY and WINGDIAPI defined properly. */ -# if 0 - /* This would put tons of macros and crap in our clean name space. */ -# define WIN32_LEAN_AND_MEAN -# include -# else - /* XXX This is from Win32's */ -# ifndef APIENTRY -# define GLUT_APIENTRY_DEFINED -# if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) || defined(__BORLANDC__) || defined(__LCC__) -# define APIENTRY __stdcall -# else -# define APIENTRY -# endif -# endif - /* XXX This is from Win32's */ -# ifndef CALLBACK -# if (defined(_M_MRX000) || defined(_M_IX86) || defined(_M_ALPHA) || defined(_M_PPC)) && !defined(MIDL_PASS) || defined(__LCC__) -# define CALLBACK __stdcall -# else -# define CALLBACK -# endif -# endif - /* XXX Hack for lcc compiler. It doesn't support __declspec(dllimport), just __stdcall. */ -# if defined( __LCC__ ) -# undef WINGDIAPI -# define WINGDIAPI __stdcall -# else - /* XXX This is from Win32's and */ -# ifndef WINGDIAPI -# define GLUT_WINGDIAPI_DEFINED -# define WINGDIAPI __declspec(dllimport) -# endif -# endif - /* XXX This is from Win32's */ -# ifndef _WCHAR_T_DEFINED -typedef unsigned short wchar_t; -# define _WCHAR_T_DEFINED -# endif -# endif - -/* To disable automatic library usage for GLUT, define GLUT_NO_LIB_PRAGMA - in your compile preprocessor options. */ -# if !defined(GLUT_BUILDING_LIB) && !defined(GLUT_NO_LIB_PRAGMA) -# pragma comment (lib, "winmm.lib") /* link with Windows MultiMedia lib */ -/* To enable automatic SGI OpenGL for Windows library usage for GLUT, - define GLUT_USE_SGI_OPENGL in your compile preprocessor options. */ -# ifdef GLUT_USE_SGI_OPENGL -# pragma comment (lib, "opengl.lib") /* link with SGI OpenGL for Windows lib */ -# pragma comment (lib, "glu.lib") /* link with SGI OpenGL Utility lib */ -# pragma comment (lib, "glut.lib") /* link with Win32 GLUT for SGI OpenGL lib */ -# else -# pragma comment (lib, "opengl32.lib") /* link with Microsoft OpenGL lib */ -# pragma comment (lib, "glu32.lib") /* link with Microsoft OpenGL Utility lib */ -# pragma comment (lib, "glut32.lib") /* link with Win32 GLUT lib */ -# endif -# endif - -/* To disable supression of annoying warnings about floats being promoted - to doubles, define GLUT_NO_WARNING_DISABLE in your compile preprocessor - options. */ -# ifndef GLUT_NO_WARNING_DISABLE -# pragma warning (disable:4244) /* Disable bogus VC++ 4.2 conversion warnings. */ -# pragma warning (disable:4305) /* VC++ 5.0 version of above warning. */ -# endif - -/* Win32 has an annoying issue where there are multiple C run-time - libraries (CRTs). If the executable is linked with a different CRT - from the GLUT DLL, the GLUT DLL will not share the same CRT static - data seen by the executable. In particular, atexit callbacks registered - in the executable will not be called if GLUT calls its (different) - exit routine). GLUT is typically built with the - "/MD" option (the CRT with multithreading DLL support), but the Visual - C++ linker default is "/ML" (the single threaded CRT). - - One workaround to this issue is requiring users to always link with - the same CRT as GLUT is compiled with. That requires users supply a - non-standard option. GLUT 3.7 has its own built-in workaround where - the executable's "exit" function pointer is covertly passed to GLUT. - GLUT then calls the executable's exit function pointer to ensure that - any "atexit" calls registered by the application are called if GLUT - needs to exit. - - Note that the __glut*WithExit routines should NEVER be called directly. - To avoid the atexit workaround, #define GLUT_DISABLE_ATEXIT_HACK. */ - -/* XXX This is from Win32's */ -# if !defined(_MSC_VER) && !defined(__cdecl) - /* Define __cdecl for non-Microsoft compilers. */ -# define __cdecl -# define GLUT_DEFINED___CDECL -# endif -# ifndef _CRTIMP -# ifdef _NTSDK - /* Definition compatible with NT SDK */ -# define _CRTIMP -# else - /* Current definition */ -# ifdef _DLL -# define _CRTIMP __declspec(dllimport) -# else -# define _CRTIMP -# endif -# endif -# define GLUT_DEFINED__CRTIMP -# endif - -/* GLUT API entry point declarations for Win32. */ -# ifdef GLUT_BUILDING_LIB -# define GLUTAPI __declspec(dllexport) -# else -# ifdef _DLL -# define GLUTAPI __declspec(dllimport) -# else -# define GLUTAPI extern -# endif -# endif - -/* GLUT callback calling convention for Win32. */ -# define GLUTCALLBACK __cdecl - -#endif /* _WIN32 */ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(_WIN32) -# ifndef GLUT_BUILDING_LIB -extern _CRTIMP void __cdecl exit(int); -# endif -#else -/* non-Win32 case. */ -/* Define APIENTRY and CALLBACK to nothing if we aren't on Win32. */ -# define APIENTRY -# define GLUT_APIENTRY_DEFINED -# define CALLBACK -/* Define GLUTAPI and GLUTCALLBACK as below if we aren't on Win32. */ -# define GLUTAPI extern -# define GLUTCALLBACK -/* Prototype exit for the non-Win32 case (see above). */ -extern void exit(int); -#endif - -/** - GLUT API revision history: - - GLUT_API_VERSION is updated to reflect incompatible GLUT - API changes (interface changes, semantic changes, deletions, - or additions). - - GLUT_API_VERSION=1 First public release of GLUT. 11/29/94 - - GLUT_API_VERSION=2 Added support for OpenGL/GLX multisampling, - extension. Supports new input devices like tablet, dial and button - box, and Spaceball. Easy to query OpenGL extensions. - - GLUT_API_VERSION=3 glutMenuStatus added. - - GLUT_API_VERSION=4 glutInitDisplayString, glutWarpPointer, - glutBitmapLength, glutStrokeLength, glutWindowStatusFunc, dynamic - video resize subAPI, glutPostWindowRedisplay, glutKeyboardUpFunc, - glutSpecialUpFunc, glutIgnoreKeyRepeat, glutSetKeyRepeat, - glutJoystickFunc, glutForceJoystickFunc (NOT FINALIZED!). -**/ -#ifndef GLUT_API_VERSION /* allow this to be overriden */ -#define GLUT_API_VERSION 3 -#endif - -/** - GLUT implementation revision history: - - GLUT_XLIB_IMPLEMENTATION is updated to reflect both GLUT - API revisions and implementation revisions (ie, bug fixes). - - GLUT_XLIB_IMPLEMENTATION=1 mjk's first public release of - GLUT Xlib-based implementation. 11/29/94 - - GLUT_XLIB_IMPLEMENTATION=2 mjk's second public release of - GLUT Xlib-based implementation providing GLUT version 2 - interfaces. - - GLUT_XLIB_IMPLEMENTATION=3 mjk's GLUT 2.2 images. 4/17/95 - - GLUT_XLIB_IMPLEMENTATION=4 mjk's GLUT 2.3 images. 6/?/95 - - GLUT_XLIB_IMPLEMENTATION=5 mjk's GLUT 3.0 images. 10/?/95 - - GLUT_XLIB_IMPLEMENTATION=7 mjk's GLUT 3.1+ with glutWarpPoitner. 7/24/96 - - GLUT_XLIB_IMPLEMENTATION=8 mjk's GLUT 3.1+ with glutWarpPoitner - and video resize. 1/3/97 - - GLUT_XLIB_IMPLEMENTATION=9 mjk's GLUT 3.4 release with early GLUT 4 routines. - - GLUT_XLIB_IMPLEMENTATION=11 Mesa 2.5's GLUT 3.6 release. - - GLUT_XLIB_IMPLEMENTATION=12 mjk's GLUT 3.6 release with early GLUT 4 routines + signal handling. - - GLUT_XLIB_IMPLEMENTATION=13 mjk's GLUT 3.7 beta with GameGLUT support. - - GLUT_XLIB_IMPLEMENTATION=14 mjk's GLUT 3.7 beta with f90gl friend interface. - - GLUT_XLIB_IMPLEMENTATION=15 mjk's GLUT 3.7 beta sync'ed with Mesa -**/ -#ifndef GLUT_XLIB_IMPLEMENTATION /* Allow this to be overriden. */ -#define GLUT_XLIB_IMPLEMENTATION 15 -#endif - -/* Display mode bit masks. */ -#define GLUT_RGB 0 -#define GLUT_RGBA GLUT_RGB -#define GLUT_INDEX 1 -#define GLUT_SINGLE 0 -#define GLUT_DOUBLE 2 -#define GLUT_ACCUM 4 -#define GLUT_ALPHA 8 -#define GLUT_DEPTH 16 -#define GLUT_STENCIL 32 -#if (GLUT_API_VERSION >= 2) -#define GLUT_MULTISAMPLE 128 -#define GLUT_STEREO 256 -#endif -#if (GLUT_API_VERSION >= 3) -#define GLUT_LUMINANCE 512 -#endif - -/* Mouse buttons. */ -#define GLUT_LEFT_BUTTON 0 -#define GLUT_MIDDLE_BUTTON 1 -#define GLUT_RIGHT_BUTTON 2 - -/* Mouse button state. */ -#define GLUT_DOWN 0 -#define GLUT_UP 1 - -#if (GLUT_API_VERSION >= 2) -/* function keys */ -#define GLUT_KEY_F1 1 -#define GLUT_KEY_F2 2 -#define GLUT_KEY_F3 3 -#define GLUT_KEY_F4 4 -#define GLUT_KEY_F5 5 -#define GLUT_KEY_F6 6 -#define GLUT_KEY_F7 7 -#define GLUT_KEY_F8 8 -#define GLUT_KEY_F9 9 -#define GLUT_KEY_F10 10 -#define GLUT_KEY_F11 11 -#define GLUT_KEY_F12 12 -/* directional keys */ -#define GLUT_KEY_LEFT 100 -#define GLUT_KEY_UP 101 -#define GLUT_KEY_RIGHT 102 -#define GLUT_KEY_DOWN 103 -#define GLUT_KEY_PAGE_UP 104 -#define GLUT_KEY_PAGE_DOWN 105 -#define GLUT_KEY_HOME 106 -#define GLUT_KEY_END 107 -#define GLUT_KEY_INSERT 108 -#endif - -/* Entry/exit state. */ -#define GLUT_LEFT 0 -#define GLUT_ENTERED 1 - -/* Menu usage state. */ -#define GLUT_MENU_NOT_IN_USE 0 -#define GLUT_MENU_IN_USE 1 - -/* Visibility state. */ -#define GLUT_NOT_VISIBLE 0 -#define GLUT_VISIBLE 1 - -/* Window status state. */ -#define GLUT_HIDDEN 0 -#define GLUT_FULLY_RETAINED 1 -#define GLUT_PARTIALLY_RETAINED 2 -#define GLUT_FULLY_COVERED 3 - -/* Color index component selection values. */ -#define GLUT_RED 0 -#define GLUT_GREEN 1 -#define GLUT_BLUE 2 - -#if defined(_WIN32) -/* Stroke font constants (use these in GLUT program). */ -#define GLUT_STROKE_ROMAN ((void*)0) -#define GLUT_STROKE_MONO_ROMAN ((void*)1) - -/* Bitmap font constants (use these in GLUT program). */ -#define GLUT_BITMAP_9_BY_15 ((void*)2) -#define GLUT_BITMAP_8_BY_13 ((void*)3) -#define GLUT_BITMAP_TIMES_ROMAN_10 ((void*)4) -#define GLUT_BITMAP_TIMES_ROMAN_24 ((void*)5) -#if (GLUT_API_VERSION >= 3) -#define GLUT_BITMAP_HELVETICA_10 ((void*)6) -#define GLUT_BITMAP_HELVETICA_12 ((void*)7) -#define GLUT_BITMAP_HELVETICA_18 ((void*)8) -#endif -#else -/* Stroke font opaque addresses (use constants instead in source code). */ -GLUTAPI void *glutStrokeRoman; -GLUTAPI void *glutStrokeMonoRoman; - -/* Stroke font constants (use these in GLUT program). */ -#define GLUT_STROKE_ROMAN (&glutStrokeRoman) -#define GLUT_STROKE_MONO_ROMAN (&glutStrokeMonoRoman) - -/* Bitmap font opaque addresses (use constants instead in source code). */ -GLUTAPI void *glutBitmap9By15; -GLUTAPI void *glutBitmap8By13; -GLUTAPI void *glutBitmapTimesRoman10; -GLUTAPI void *glutBitmapTimesRoman24; -GLUTAPI void *glutBitmapHelvetica10; -GLUTAPI void *glutBitmapHelvetica12; -GLUTAPI void *glutBitmapHelvetica18; - -/* Bitmap font constants (use these in GLUT program). */ -#define GLUT_BITMAP_9_BY_15 (&glutBitmap9By15) -#define GLUT_BITMAP_8_BY_13 (&glutBitmap8By13) -#define GLUT_BITMAP_TIMES_ROMAN_10 (&glutBitmapTimesRoman10) -#define GLUT_BITMAP_TIMES_ROMAN_24 (&glutBitmapTimesRoman24) -#if (GLUT_API_VERSION >= 3) -#define GLUT_BITMAP_HELVETICA_10 (&glutBitmapHelvetica10) -#define GLUT_BITMAP_HELVETICA_12 (&glutBitmapHelvetica12) -#define GLUT_BITMAP_HELVETICA_18 (&glutBitmapHelvetica18) -#endif -#endif - -/* glutGet parameters. */ -#define GLUT_WINDOW_X ((GLenum) 100) -#define GLUT_WINDOW_Y ((GLenum) 101) -#define GLUT_WINDOW_WIDTH ((GLenum) 102) -#define GLUT_WINDOW_HEIGHT ((GLenum) 103) -#define GLUT_WINDOW_BUFFER_SIZE ((GLenum) 104) -#define GLUT_WINDOW_STENCIL_SIZE ((GLenum) 105) -#define GLUT_WINDOW_DEPTH_SIZE ((GLenum) 106) -#define GLUT_WINDOW_RED_SIZE ((GLenum) 107) -#define GLUT_WINDOW_GREEN_SIZE ((GLenum) 108) -#define GLUT_WINDOW_BLUE_SIZE ((GLenum) 109) -#define GLUT_WINDOW_ALPHA_SIZE ((GLenum) 110) -#define GLUT_WINDOW_ACCUM_RED_SIZE ((GLenum) 111) -#define GLUT_WINDOW_ACCUM_GREEN_SIZE ((GLenum) 112) -#define GLUT_WINDOW_ACCUM_BLUE_SIZE ((GLenum) 113) -#define GLUT_WINDOW_ACCUM_ALPHA_SIZE ((GLenum) 114) -#define GLUT_WINDOW_DOUBLEBUFFER ((GLenum) 115) -#define GLUT_WINDOW_RGBA ((GLenum) 116) -#define GLUT_WINDOW_PARENT ((GLenum) 117) -#define GLUT_WINDOW_NUM_CHILDREN ((GLenum) 118) -#define GLUT_WINDOW_COLORMAP_SIZE ((GLenum) 119) -#if (GLUT_API_VERSION >= 2) -#define GLUT_WINDOW_NUM_SAMPLES ((GLenum) 120) -#define GLUT_WINDOW_STEREO ((GLenum) 121) -#endif -#if (GLUT_API_VERSION >= 3) -#define GLUT_WINDOW_CURSOR ((GLenum) 122) -#endif -#define GLUT_SCREEN_WIDTH ((GLenum) 200) -#define GLUT_SCREEN_HEIGHT ((GLenum) 201) -#define GLUT_SCREEN_WIDTH_MM ((GLenum) 202) -#define GLUT_SCREEN_HEIGHT_MM ((GLenum) 203) -#define GLUT_MENU_NUM_ITEMS ((GLenum) 300) -#define GLUT_DISPLAY_MODE_POSSIBLE ((GLenum) 400) -#define GLUT_INIT_WINDOW_X ((GLenum) 500) -#define GLUT_INIT_WINDOW_Y ((GLenum) 501) -#define GLUT_INIT_WINDOW_WIDTH ((GLenum) 502) -#define GLUT_INIT_WINDOW_HEIGHT ((GLenum) 503) -#define GLUT_INIT_DISPLAY_MODE ((GLenum) 504) -#if (GLUT_API_VERSION >= 2) -#define GLUT_ELAPSED_TIME ((GLenum) 700) -#endif -#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) -#define GLUT_WINDOW_FORMAT_ID ((GLenum) 123) -#endif - -#if (GLUT_API_VERSION >= 2) -/* glutDeviceGet parameters. */ -#define GLUT_HAS_KEYBOARD ((GLenum) 600) -#define GLUT_HAS_MOUSE ((GLenum) 601) -#define GLUT_HAS_SPACEBALL ((GLenum) 602) -#define GLUT_HAS_DIAL_AND_BUTTON_BOX ((GLenum) 603) -#define GLUT_HAS_TABLET ((GLenum) 604) -#define GLUT_NUM_MOUSE_BUTTONS ((GLenum) 605) -#define GLUT_NUM_SPACEBALL_BUTTONS ((GLenum) 606) -#define GLUT_NUM_BUTTON_BOX_BUTTONS ((GLenum) 607) -#define GLUT_NUM_DIALS ((GLenum) 608) -#define GLUT_NUM_TABLET_BUTTONS ((GLenum) 609) -#endif -#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) -#define GLUT_DEVICE_IGNORE_KEY_REPEAT ((GLenum) 610) -#define GLUT_DEVICE_KEY_REPEAT ((GLenum) 611) -#define GLUT_HAS_JOYSTICK ((GLenum) 612) -#define GLUT_OWNS_JOYSTICK ((GLenum) 613) -#define GLUT_JOYSTICK_BUTTONS ((GLenum) 614) -#define GLUT_JOYSTICK_AXES ((GLenum) 615) -#define GLUT_JOYSTICK_POLL_RATE ((GLenum) 616) -#endif - -#if (GLUT_API_VERSION >= 3) -/* glutLayerGet parameters. */ -#define GLUT_OVERLAY_POSSIBLE ((GLenum) 800) -#define GLUT_LAYER_IN_USE ((GLenum) 801) -#define GLUT_HAS_OVERLAY ((GLenum) 802) -#define GLUT_TRANSPARENT_INDEX ((GLenum) 803) -#define GLUT_NORMAL_DAMAGED ((GLenum) 804) -#define GLUT_OVERLAY_DAMAGED ((GLenum) 805) - -#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) -/* glutVideoResizeGet parameters. */ -#define GLUT_VIDEO_RESIZE_POSSIBLE ((GLenum) 900) -#define GLUT_VIDEO_RESIZE_IN_USE ((GLenum) 901) -#define GLUT_VIDEO_RESIZE_X_DELTA ((GLenum) 902) -#define GLUT_VIDEO_RESIZE_Y_DELTA ((GLenum) 903) -#define GLUT_VIDEO_RESIZE_WIDTH_DELTA ((GLenum) 904) -#define GLUT_VIDEO_RESIZE_HEIGHT_DELTA ((GLenum) 905) -#define GLUT_VIDEO_RESIZE_X ((GLenum) 906) -#define GLUT_VIDEO_RESIZE_Y ((GLenum) 907) -#define GLUT_VIDEO_RESIZE_WIDTH ((GLenum) 908) -#define GLUT_VIDEO_RESIZE_HEIGHT ((GLenum) 909) -#endif - -/* glutUseLayer parameters. */ -#define GLUT_NORMAL ((GLenum) 0) -#define GLUT_OVERLAY ((GLenum) 1) - -/* glutGetModifiers return mask. */ -#define GLUT_ACTIVE_SHIFT 1 -#define GLUT_ACTIVE_CTRL 2 -#define GLUT_ACTIVE_ALT 4 - -/* glutSetCursor parameters. */ -/* Basic arrows. */ -#define GLUT_CURSOR_RIGHT_ARROW 0 -#define GLUT_CURSOR_LEFT_ARROW 1 -/* Symbolic cursor shapes. */ -#define GLUT_CURSOR_INFO 2 -#define GLUT_CURSOR_DESTROY 3 -#define GLUT_CURSOR_HELP 4 -#define GLUT_CURSOR_CYCLE 5 -#define GLUT_CURSOR_SPRAY 6 -#define GLUT_CURSOR_WAIT 7 -#define GLUT_CURSOR_TEXT 8 -#define GLUT_CURSOR_CROSSHAIR 9 -/* Directional cursors. */ -#define GLUT_CURSOR_UP_DOWN 10 -#define GLUT_CURSOR_LEFT_RIGHT 11 -/* Sizing cursors. */ -#define GLUT_CURSOR_TOP_SIDE 12 -#define GLUT_CURSOR_BOTTOM_SIDE 13 -#define GLUT_CURSOR_LEFT_SIDE 14 -#define GLUT_CURSOR_RIGHT_SIDE 15 -#define GLUT_CURSOR_TOP_LEFT_CORNER 16 -#define GLUT_CURSOR_TOP_RIGHT_CORNER 17 -#define GLUT_CURSOR_BOTTOM_RIGHT_CORNER 18 -#define GLUT_CURSOR_BOTTOM_LEFT_CORNER 19 -/* Inherit from parent window. */ -#define GLUT_CURSOR_INHERIT 100 -/* Blank cursor. */ -#define GLUT_CURSOR_NONE 101 -/* Fullscreen crosshair (if available). */ -#define GLUT_CURSOR_FULL_CROSSHAIR 102 -#endif - -/* GLUT initialization sub-API. */ -GLUTAPI void APIENTRY glutInit(int *argcp, char **argv); -#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK) -GLUTAPI void APIENTRY __glutInitWithExit(int *argcp, char **argv, void (__cdecl *exitfunc)(int)); -#ifndef GLUT_BUILDING_LIB -static void APIENTRY glutInit_ATEXIT_HACK(int *argcp, char **argv) { __glutInitWithExit(argcp, argv, exit); } -#define glutInit glutInit_ATEXIT_HACK -#endif -#endif -GLUTAPI void APIENTRY glutInitDisplayMode(unsigned int mode); -#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) -GLUTAPI void APIENTRY glutInitDisplayString(const char *string); -#endif -GLUTAPI void APIENTRY glutInitWindowPosition(int x, int y); -GLUTAPI void APIENTRY glutInitWindowSize(int width, int height); -GLUTAPI void APIENTRY glutMainLoop(void); - -/* GLUT window sub-API. */ -GLUTAPI int APIENTRY glutCreateWindow(const char *title); -#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK) -GLUTAPI int APIENTRY __glutCreateWindowWithExit(const char *title, void (__cdecl *exitfunc)(int)); -#ifndef GLUT_BUILDING_LIB -static int APIENTRY glutCreateWindow_ATEXIT_HACK(const char *title) { return __glutCreateWindowWithExit(title, exit); } -#define glutCreateWindow glutCreateWindow_ATEXIT_HACK -#endif -#endif -GLUTAPI int APIENTRY glutCreateSubWindow(int win, int x, int y, int width, int height); -GLUTAPI void APIENTRY glutDestroyWindow(int win); -GLUTAPI void APIENTRY glutPostRedisplay(void); -#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 11) -GLUTAPI void APIENTRY glutPostWindowRedisplay(int win); -#endif -GLUTAPI void APIENTRY glutSwapBuffers(void); -GLUTAPI int APIENTRY glutGetWindow(void); -GLUTAPI void APIENTRY glutSetWindow(int win); -GLUTAPI void APIENTRY glutSetWindowTitle(const char *title); -GLUTAPI void APIENTRY glutSetIconTitle(const char *title); -GLUTAPI void APIENTRY glutPositionWindow(int x, int y); -GLUTAPI void APIENTRY glutReshapeWindow(int width, int height); -GLUTAPI void APIENTRY glutPopWindow(void); -GLUTAPI void APIENTRY glutPushWindow(void); -GLUTAPI void APIENTRY glutIconifyWindow(void); -GLUTAPI void APIENTRY glutShowWindow(void); -GLUTAPI void APIENTRY glutHideWindow(void); -#if (GLUT_API_VERSION >= 3) -GLUTAPI void APIENTRY glutFullScreen(void); -GLUTAPI void APIENTRY glutSetCursor(int cursor); -#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) -GLUTAPI void APIENTRY glutWarpPointer(int x, int y); -#endif - -/* GLUT overlay sub-API. */ -GLUTAPI void APIENTRY glutEstablishOverlay(void); -GLUTAPI void APIENTRY glutRemoveOverlay(void); -GLUTAPI void APIENTRY glutUseLayer(GLenum layer); -GLUTAPI void APIENTRY glutPostOverlayRedisplay(void); -#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 11) -GLUTAPI void APIENTRY glutPostWindowOverlayRedisplay(int win); -#endif -GLUTAPI void APIENTRY glutShowOverlay(void); -GLUTAPI void APIENTRY glutHideOverlay(void); -#endif - -/* GLUT menu sub-API. */ -GLUTAPI int APIENTRY glutCreateMenu(void (GLUTCALLBACK *func)(int)); -#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK) -GLUTAPI int APIENTRY __glutCreateMenuWithExit(void (GLUTCALLBACK *func)(int), void (__cdecl *exitfunc)(int)); -#ifndef GLUT_BUILDING_LIB -static int APIENTRY glutCreateMenu_ATEXIT_HACK(void (GLUTCALLBACK *func)(int)) { return __glutCreateMenuWithExit(func, exit); } -#define glutCreateMenu glutCreateMenu_ATEXIT_HACK -#endif -#endif -GLUTAPI void APIENTRY glutDestroyMenu(int menu); -GLUTAPI int APIENTRY glutGetMenu(void); -GLUTAPI void APIENTRY glutSetMenu(int menu); -GLUTAPI void APIENTRY glutAddMenuEntry(const char *label, int value); -GLUTAPI void APIENTRY glutAddSubMenu(const char *label, int submenu); -GLUTAPI void APIENTRY glutChangeToMenuEntry(int item, const char *label, int value); -GLUTAPI void APIENTRY glutChangeToSubMenu(int item, const char *label, int submenu); -GLUTAPI void APIENTRY glutRemoveMenuItem(int item); -GLUTAPI void APIENTRY glutAttachMenu(int button); -GLUTAPI void APIENTRY glutDetachMenu(int button); - -/* GLUT window callback sub-API. */ -GLUTAPI void APIENTRY glutDisplayFunc(void (GLUTCALLBACK *func)(void)); -GLUTAPI void APIENTRY glutReshapeFunc(void (GLUTCALLBACK *func)(int width, int height)); -GLUTAPI void APIENTRY glutKeyboardFunc(void (GLUTCALLBACK *func)(unsigned char key, int x, int y)); -GLUTAPI void APIENTRY glutMouseFunc(void (GLUTCALLBACK *func)(int button, int state, int x, int y)); -GLUTAPI void APIENTRY glutMotionFunc(void (GLUTCALLBACK *func)(int x, int y)); -GLUTAPI void APIENTRY glutPassiveMotionFunc(void (GLUTCALLBACK *func)(int x, int y)); -GLUTAPI void APIENTRY glutEntryFunc(void (GLUTCALLBACK *func)(int state)); -GLUTAPI void APIENTRY glutVisibilityFunc(void (GLUTCALLBACK *func)(int state)); -GLUTAPI void APIENTRY glutIdleFunc(void (GLUTCALLBACK *func)(void)); -GLUTAPI void APIENTRY glutTimerFunc(unsigned int millis, void (GLUTCALLBACK *func)(int value), int value); -GLUTAPI void APIENTRY glutMenuStateFunc(void (GLUTCALLBACK *func)(int state)); -#if (GLUT_API_VERSION >= 2) -GLUTAPI void APIENTRY glutSpecialFunc(void (GLUTCALLBACK *func)(int key, int x, int y)); -GLUTAPI void APIENTRY glutSpaceballMotionFunc(void (GLUTCALLBACK *func)(int x, int y, int z)); -GLUTAPI void APIENTRY glutSpaceballRotateFunc(void (GLUTCALLBACK *func)(int x, int y, int z)); -GLUTAPI void APIENTRY glutSpaceballButtonFunc(void (GLUTCALLBACK *func)(int button, int state)); -GLUTAPI void APIENTRY glutButtonBoxFunc(void (GLUTCALLBACK *func)(int button, int state)); -GLUTAPI void APIENTRY glutDialsFunc(void (GLUTCALLBACK *func)(int dial, int value)); -GLUTAPI void APIENTRY glutTabletMotionFunc(void (GLUTCALLBACK *func)(int x, int y)); -GLUTAPI void APIENTRY glutTabletButtonFunc(void (GLUTCALLBACK *func)(int button, int state, int x, int y)); -#if (GLUT_API_VERSION >= 3) -GLUTAPI void APIENTRY glutMenuStatusFunc(void (GLUTCALLBACK *func)(int status, int x, int y)); -GLUTAPI void APIENTRY glutOverlayDisplayFunc(void (GLUTCALLBACK *func)(void)); -#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) -GLUTAPI void APIENTRY glutWindowStatusFunc(void (GLUTCALLBACK *func)(int state)); -#endif -#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) -GLUTAPI void APIENTRY glutKeyboardUpFunc(void (GLUTCALLBACK *func)(unsigned char key, int x, int y)); -GLUTAPI void APIENTRY glutSpecialUpFunc(void (GLUTCALLBACK *func)(int key, int x, int y)); -GLUTAPI void APIENTRY glutJoystickFunc(void (GLUTCALLBACK *func)(unsigned int buttonMask, int x, int y, int z), int pollInterval); -#endif -#endif -#endif - -/* GLUT color index sub-API. */ -GLUTAPI void APIENTRY glutSetColor(int, GLfloat red, GLfloat green, GLfloat blue); -GLUTAPI GLfloat APIENTRY glutGetColor(int ndx, int component); -GLUTAPI void APIENTRY glutCopyColormap(int win); - -/* GLUT state retrieval sub-API. */ -GLUTAPI int APIENTRY glutGet(GLenum type); -GLUTAPI int APIENTRY glutDeviceGet(GLenum type); -#if (GLUT_API_VERSION >= 2) -/* GLUT extension support sub-API */ -GLUTAPI int APIENTRY glutExtensionSupported(const char *name); -#endif -#if (GLUT_API_VERSION >= 3) -GLUTAPI int APIENTRY glutGetModifiers(void); -GLUTAPI int APIENTRY glutLayerGet(GLenum type); -#endif - -/* GLUT font sub-API */ -GLUTAPI void APIENTRY glutBitmapCharacter(void *font, int character); -GLUTAPI int APIENTRY glutBitmapWidth(void *font, int character); -GLUTAPI void APIENTRY glutStrokeCharacter(void *font, int character); -GLUTAPI int APIENTRY glutStrokeWidth(void *font, int character); -#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) -GLUTAPI int APIENTRY glutBitmapLength(void *font, const unsigned char *string); -GLUTAPI int APIENTRY glutStrokeLength(void *font, const unsigned char *string); -#endif - -/* GLUT pre-built models sub-API */ -GLUTAPI void APIENTRY glutWireSphere(GLdouble radius, GLint slices, GLint stacks); -GLUTAPI void APIENTRY glutSolidSphere(GLdouble radius, GLint slices, GLint stacks); -GLUTAPI void APIENTRY glutWireCone(GLdouble base, GLdouble height, GLint slices, GLint stacks); -GLUTAPI void APIENTRY glutSolidCone(GLdouble base, GLdouble height, GLint slices, GLint stacks); -GLUTAPI void APIENTRY glutWireCube(GLdouble size); -GLUTAPI void APIENTRY glutSolidCube(GLdouble size); -GLUTAPI void APIENTRY glutWireTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings); -GLUTAPI void APIENTRY glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings); -GLUTAPI void APIENTRY glutWireDodecahedron(void); -GLUTAPI void APIENTRY glutSolidDodecahedron(void); -GLUTAPI void APIENTRY glutWireTeapot(GLdouble size); -GLUTAPI void APIENTRY glutSolidTeapot(GLdouble size); -GLUTAPI void APIENTRY glutWireOctahedron(void); -GLUTAPI void APIENTRY glutSolidOctahedron(void); -GLUTAPI void APIENTRY glutWireTetrahedron(void); -GLUTAPI void APIENTRY glutSolidTetrahedron(void); -GLUTAPI void APIENTRY glutWireIcosahedron(void); -GLUTAPI void APIENTRY glutSolidIcosahedron(void); - -#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) -/* GLUT video resize sub-API. */ -GLUTAPI int APIENTRY glutVideoResizeGet(GLenum param); -GLUTAPI void APIENTRY glutSetupVideoResizing(void); -GLUTAPI void APIENTRY glutStopVideoResizing(void); -GLUTAPI void APIENTRY glutVideoResize(int x, int y, int width, int height); -GLUTAPI void APIENTRY glutVideoPan(int x, int y, int width, int height); - -/* GLUT debugging sub-API. */ -GLUTAPI void APIENTRY glutReportErrors(void); -#endif - -#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) -/* GLUT device control sub-API. */ -/* glutSetKeyRepeat modes. */ -#define GLUT_KEY_REPEAT_OFF 0 -#define GLUT_KEY_REPEAT_ON 1 -#define GLUT_KEY_REPEAT_DEFAULT 2 - -/* Joystick button masks. */ -#define GLUT_JOYSTICK_BUTTON_A 1 -#define GLUT_JOYSTICK_BUTTON_B 2 -#define GLUT_JOYSTICK_BUTTON_C 4 -#define GLUT_JOYSTICK_BUTTON_D 8 - -GLUTAPI void APIENTRY glutIgnoreKeyRepeat(int ignore); -GLUTAPI void APIENTRY glutSetKeyRepeat(int repeatMode); -GLUTAPI void APIENTRY glutForceJoystickFunc(void); - -/* GLUT game mode sub-API. */ -/* glutGameModeGet. */ -#define GLUT_GAME_MODE_ACTIVE ((GLenum) 0) -#define GLUT_GAME_MODE_POSSIBLE ((GLenum) 1) -#define GLUT_GAME_MODE_WIDTH ((GLenum) 2) -#define GLUT_GAME_MODE_HEIGHT ((GLenum) 3) -#define GLUT_GAME_MODE_PIXEL_DEPTH ((GLenum) 4) -#define GLUT_GAME_MODE_REFRESH_RATE ((GLenum) 5) -#define GLUT_GAME_MODE_DISPLAY_CHANGED ((GLenum) 6) - -GLUTAPI void APIENTRY glutGameModeString(const char *string); -GLUTAPI int APIENTRY glutEnterGameMode(void); -GLUTAPI void APIENTRY glutLeaveGameMode(void); -GLUTAPI int APIENTRY glutGameModeGet(GLenum mode); -#endif - -#ifdef __cplusplus -} - -#endif - -#ifdef GLUT_APIENTRY_DEFINED -# undef GLUT_APIENTRY_DEFINED -# undef APIENTRY -#endif - -#ifdef GLUT_WINGDIAPI_DEFINED -# undef GLUT_WINGDIAPI_DEFINED -# undef WINGDIAPI -#endif - -#ifdef GLUT_DEFINED___CDECL -# undef GLUT_DEFINED___CDECL -# undef __cdecl -#endif - -#ifdef GLUT_DEFINED__CRTIMP -# undef GLUT_DEFINED__CRTIMP -# undef _CRTIMP -#endif - -#endif /* __glut_h__ */ +#ifndef __glut_h__ +#define __glut_h__ + +/* Copyright (c) Mark J. Kilgard, 1994, 1995, 1996, 1998. */ + +/* This program is freely distributable without licensing fees and is + provided without guarantee or warrantee expressed or implied. This + program is -not- in the public domain. */ + +#if defined(_WIN32) + +/* GLUT 3.7 now tries to avoid including + to avoid name space pollution, but Win32's + needs APIENTRY and WINGDIAPI defined properly. */ +# if 0 + /* This would put tons of macros and crap in our clean name space. */ +# define WIN32_LEAN_AND_MEAN +# include +# else + /* XXX This is from Win32's */ +# ifndef APIENTRY +# define GLUT_APIENTRY_DEFINED +# if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) || defined(__BORLANDC__) || defined(__LCC__) +# define APIENTRY __stdcall +# else +# define APIENTRY +# endif +# endif + /* XXX This is from Win32's */ +# ifndef CALLBACK +# if (defined(_M_MRX000) || defined(_M_IX86) || defined(_M_ALPHA) || defined(_M_PPC)) && !defined(MIDL_PASS) || defined(__LCC__) +# define CALLBACK __stdcall +# else +# define CALLBACK +# endif +# endif + /* XXX Hack for lcc compiler. It doesn't support __declspec(dllimport), just __stdcall. */ +# if defined( __LCC__ ) +# undef WINGDIAPI +# define WINGDIAPI __stdcall +# else + /* XXX This is from Win32's and */ +# ifndef WINGDIAPI +# define GLUT_WINGDIAPI_DEFINED +# define WINGDIAPI __declspec(dllimport) +# endif +# endif + /* XXX This is from Win32's */ +# ifndef _WCHAR_T_DEFINED +typedef unsigned short wchar_t; +# define _WCHAR_T_DEFINED +# endif +# endif + +/* To disable automatic library usage for GLUT, define GLUT_NO_LIB_PRAGMA + in your compile preprocessor options. */ +# if !defined(GLUT_BUILDING_LIB) && !defined(GLUT_NO_LIB_PRAGMA) +# pragma comment (lib, "winmm.lib") /* link with Windows MultiMedia lib */ +/* To enable automatic SGI OpenGL for Windows library usage for GLUT, + define GLUT_USE_SGI_OPENGL in your compile preprocessor options. */ +# ifdef GLUT_USE_SGI_OPENGL +# pragma comment (lib, "opengl.lib") /* link with SGI OpenGL for Windows lib */ +# pragma comment (lib, "glu.lib") /* link with SGI OpenGL Utility lib */ +# pragma comment (lib, "glut.lib") /* link with Win32 GLUT for SGI OpenGL lib */ +# else +# pragma comment (lib, "opengl32.lib") /* link with Microsoft OpenGL lib */ +# pragma comment (lib, "glu32.lib") /* link with Microsoft OpenGL Utility lib */ +# pragma comment (lib, "glut32.lib") /* link with Win32 GLUT lib */ +# endif +# endif + +/* To disable supression of annoying warnings about floats being promoted + to doubles, define GLUT_NO_WARNING_DISABLE in your compile preprocessor + options. */ +# ifndef GLUT_NO_WARNING_DISABLE +# pragma warning (disable:4244) /* Disable bogus VC++ 4.2 conversion warnings. */ +# pragma warning (disable:4305) /* VC++ 5.0 version of above warning. */ +# endif + +/* Win32 has an annoying issue where there are multiple C run-time + libraries (CRTs). If the executable is linked with a different CRT + from the GLUT DLL, the GLUT DLL will not share the same CRT static + data seen by the executable. In particular, atexit callbacks registered + in the executable will not be called if GLUT calls its (different) + exit routine). GLUT is typically built with the + "/MD" option (the CRT with multithreading DLL support), but the Visual + C++ linker default is "/ML" (the single threaded CRT). + + One workaround to this issue is requiring users to always link with + the same CRT as GLUT is compiled with. That requires users supply a + non-standard option. GLUT 3.7 has its own built-in workaround where + the executable's "exit" function pointer is covertly passed to GLUT. + GLUT then calls the executable's exit function pointer to ensure that + any "atexit" calls registered by the application are called if GLUT + needs to exit. + + Note that the __glut*WithExit routines should NEVER be called directly. + To avoid the atexit workaround, #define GLUT_DISABLE_ATEXIT_HACK. */ + +/* XXX This is from Win32's */ +# if !defined(_MSC_VER) && !defined(__cdecl) + /* Define __cdecl for non-Microsoft compilers. */ +# define __cdecl +# define GLUT_DEFINED___CDECL +# endif +# ifndef _CRTIMP +# ifdef _NTSDK + /* Definition compatible with NT SDK */ +# define _CRTIMP +# else + /* Current definition */ +# ifdef _DLL +# define _CRTIMP __declspec(dllimport) +# else +# define _CRTIMP +# endif +# endif +# define GLUT_DEFINED__CRTIMP +# endif + +/* GLUT API entry point declarations for Win32. */ +# ifdef GLUT_BUILDING_LIB +# define GLUTAPI __declspec(dllexport) +# else +# ifdef _DLL +# define GLUTAPI __declspec(dllimport) +# else +# define GLUTAPI extern +# endif +# endif + +/* GLUT callback calling convention for Win32. */ +# define GLUTCALLBACK __cdecl + +#endif /* _WIN32 */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(_WIN32) +# ifndef GLUT_BUILDING_LIB +extern _CRTIMP void __cdecl exit(int); +# endif +#else +/* non-Win32 case. */ +/* Define APIENTRY and CALLBACK to nothing if we aren't on Win32. */ +# define APIENTRY +# define GLUT_APIENTRY_DEFINED +# define CALLBACK +/* Define GLUTAPI and GLUTCALLBACK as below if we aren't on Win32. */ +# define GLUTAPI extern +# define GLUTCALLBACK +/* Prototype exit for the non-Win32 case (see above). */ +extern void exit(int); +#endif + +/** + GLUT API revision history: + + GLUT_API_VERSION is updated to reflect incompatible GLUT + API changes (interface changes, semantic changes, deletions, + or additions). + + GLUT_API_VERSION=1 First public release of GLUT. 11/29/94 + + GLUT_API_VERSION=2 Added support for OpenGL/GLX multisampling, + extension. Supports new input devices like tablet, dial and button + box, and Spaceball. Easy to query OpenGL extensions. + + GLUT_API_VERSION=3 glutMenuStatus added. + + GLUT_API_VERSION=4 glutInitDisplayString, glutWarpPointer, + glutBitmapLength, glutStrokeLength, glutWindowStatusFunc, dynamic + video resize subAPI, glutPostWindowRedisplay, glutKeyboardUpFunc, + glutSpecialUpFunc, glutIgnoreKeyRepeat, glutSetKeyRepeat, + glutJoystickFunc, glutForceJoystickFunc (NOT FINALIZED!). +**/ +#ifndef GLUT_API_VERSION /* allow this to be overriden */ +#define GLUT_API_VERSION 3 +#endif + +/** + GLUT implementation revision history: + + GLUT_XLIB_IMPLEMENTATION is updated to reflect both GLUT + API revisions and implementation revisions (ie, bug fixes). + + GLUT_XLIB_IMPLEMENTATION=1 mjk's first public release of + GLUT Xlib-based implementation. 11/29/94 + + GLUT_XLIB_IMPLEMENTATION=2 mjk's second public release of + GLUT Xlib-based implementation providing GLUT version 2 + interfaces. + + GLUT_XLIB_IMPLEMENTATION=3 mjk's GLUT 2.2 images. 4/17/95 + + GLUT_XLIB_IMPLEMENTATION=4 mjk's GLUT 2.3 images. 6/?/95 + + GLUT_XLIB_IMPLEMENTATION=5 mjk's GLUT 3.0 images. 10/?/95 + + GLUT_XLIB_IMPLEMENTATION=7 mjk's GLUT 3.1+ with glutWarpPoitner. 7/24/96 + + GLUT_XLIB_IMPLEMENTATION=8 mjk's GLUT 3.1+ with glutWarpPoitner + and video resize. 1/3/97 + + GLUT_XLIB_IMPLEMENTATION=9 mjk's GLUT 3.4 release with early GLUT 4 routines. + + GLUT_XLIB_IMPLEMENTATION=11 Mesa 2.5's GLUT 3.6 release. + + GLUT_XLIB_IMPLEMENTATION=12 mjk's GLUT 3.6 release with early GLUT 4 routines + signal handling. + + GLUT_XLIB_IMPLEMENTATION=13 mjk's GLUT 3.7 beta with GameGLUT support. + + GLUT_XLIB_IMPLEMENTATION=14 mjk's GLUT 3.7 beta with f90gl friend interface. + + GLUT_XLIB_IMPLEMENTATION=15 mjk's GLUT 3.7 beta sync'ed with Mesa +**/ +#ifndef GLUT_XLIB_IMPLEMENTATION /* Allow this to be overriden. */ +#define GLUT_XLIB_IMPLEMENTATION 15 +#endif + +/* Display mode bit masks. */ +#define GLUT_RGB 0 +#define GLUT_RGBA GLUT_RGB +#define GLUT_INDEX 1 +#define GLUT_SINGLE 0 +#define GLUT_DOUBLE 2 +#define GLUT_ACCUM 4 +#define GLUT_ALPHA 8 +#define GLUT_DEPTH 16 +#define GLUT_STENCIL 32 +#if (GLUT_API_VERSION >= 2) +#define GLUT_MULTISAMPLE 128 +#define GLUT_STEREO 256 +#endif +#if (GLUT_API_VERSION >= 3) +#define GLUT_LUMINANCE 512 +#endif + +/* Mouse buttons. */ +#define GLUT_LEFT_BUTTON 0 +#define GLUT_MIDDLE_BUTTON 1 +#define GLUT_RIGHT_BUTTON 2 + +/* Mouse button state. */ +#define GLUT_DOWN 0 +#define GLUT_UP 1 + +#if (GLUT_API_VERSION >= 2) +/* function keys */ +#define GLUT_KEY_F1 1 +#define GLUT_KEY_F2 2 +#define GLUT_KEY_F3 3 +#define GLUT_KEY_F4 4 +#define GLUT_KEY_F5 5 +#define GLUT_KEY_F6 6 +#define GLUT_KEY_F7 7 +#define GLUT_KEY_F8 8 +#define GLUT_KEY_F9 9 +#define GLUT_KEY_F10 10 +#define GLUT_KEY_F11 11 +#define GLUT_KEY_F12 12 +/* directional keys */ +#define GLUT_KEY_LEFT 100 +#define GLUT_KEY_UP 101 +#define GLUT_KEY_RIGHT 102 +#define GLUT_KEY_DOWN 103 +#define GLUT_KEY_PAGE_UP 104 +#define GLUT_KEY_PAGE_DOWN 105 +#define GLUT_KEY_HOME 106 +#define GLUT_KEY_END 107 +#define GLUT_KEY_INSERT 108 +#endif + +/* Entry/exit state. */ +#define GLUT_LEFT 0 +#define GLUT_ENTERED 1 + +/* Menu usage state. */ +#define GLUT_MENU_NOT_IN_USE 0 +#define GLUT_MENU_IN_USE 1 + +/* Visibility state. */ +#define GLUT_NOT_VISIBLE 0 +#define GLUT_VISIBLE 1 + +/* Window status state. */ +#define GLUT_HIDDEN 0 +#define GLUT_FULLY_RETAINED 1 +#define GLUT_PARTIALLY_RETAINED 2 +#define GLUT_FULLY_COVERED 3 + +/* Color index component selection values. */ +#define GLUT_RED 0 +#define GLUT_GREEN 1 +#define GLUT_BLUE 2 + +#if defined(_WIN32) +/* Stroke font constants (use these in GLUT program). */ +#define GLUT_STROKE_ROMAN ((void*)0) +#define GLUT_STROKE_MONO_ROMAN ((void*)1) + +/* Bitmap font constants (use these in GLUT program). */ +#define GLUT_BITMAP_9_BY_15 ((void*)2) +#define GLUT_BITMAP_8_BY_13 ((void*)3) +#define GLUT_BITMAP_TIMES_ROMAN_10 ((void*)4) +#define GLUT_BITMAP_TIMES_ROMAN_24 ((void*)5) +#if (GLUT_API_VERSION >= 3) +#define GLUT_BITMAP_HELVETICA_10 ((void*)6) +#define GLUT_BITMAP_HELVETICA_12 ((void*)7) +#define GLUT_BITMAP_HELVETICA_18 ((void*)8) +#endif +#else +/* Stroke font opaque addresses (use constants instead in source code). */ +GLUTAPI void *glutStrokeRoman; +GLUTAPI void *glutStrokeMonoRoman; + +/* Stroke font constants (use these in GLUT program). */ +#define GLUT_STROKE_ROMAN (&glutStrokeRoman) +#define GLUT_STROKE_MONO_ROMAN (&glutStrokeMonoRoman) + +/* Bitmap font opaque addresses (use constants instead in source code). */ +GLUTAPI void *glutBitmap9By15; +GLUTAPI void *glutBitmap8By13; +GLUTAPI void *glutBitmapTimesRoman10; +GLUTAPI void *glutBitmapTimesRoman24; +GLUTAPI void *glutBitmapHelvetica10; +GLUTAPI void *glutBitmapHelvetica12; +GLUTAPI void *glutBitmapHelvetica18; + +/* Bitmap font constants (use these in GLUT program). */ +#define GLUT_BITMAP_9_BY_15 (&glutBitmap9By15) +#define GLUT_BITMAP_8_BY_13 (&glutBitmap8By13) +#define GLUT_BITMAP_TIMES_ROMAN_10 (&glutBitmapTimesRoman10) +#define GLUT_BITMAP_TIMES_ROMAN_24 (&glutBitmapTimesRoman24) +#if (GLUT_API_VERSION >= 3) +#define GLUT_BITMAP_HELVETICA_10 (&glutBitmapHelvetica10) +#define GLUT_BITMAP_HELVETICA_12 (&glutBitmapHelvetica12) +#define GLUT_BITMAP_HELVETICA_18 (&glutBitmapHelvetica18) +#endif +#endif + +/* glutGet parameters. */ +#define GLUT_WINDOW_X ((GLenum) 100) +#define GLUT_WINDOW_Y ((GLenum) 101) +#define GLUT_WINDOW_WIDTH ((GLenum) 102) +#define GLUT_WINDOW_HEIGHT ((GLenum) 103) +#define GLUT_WINDOW_BUFFER_SIZE ((GLenum) 104) +#define GLUT_WINDOW_STENCIL_SIZE ((GLenum) 105) +#define GLUT_WINDOW_DEPTH_SIZE ((GLenum) 106) +#define GLUT_WINDOW_RED_SIZE ((GLenum) 107) +#define GLUT_WINDOW_GREEN_SIZE ((GLenum) 108) +#define GLUT_WINDOW_BLUE_SIZE ((GLenum) 109) +#define GLUT_WINDOW_ALPHA_SIZE ((GLenum) 110) +#define GLUT_WINDOW_ACCUM_RED_SIZE ((GLenum) 111) +#define GLUT_WINDOW_ACCUM_GREEN_SIZE ((GLenum) 112) +#define GLUT_WINDOW_ACCUM_BLUE_SIZE ((GLenum) 113) +#define GLUT_WINDOW_ACCUM_ALPHA_SIZE ((GLenum) 114) +#define GLUT_WINDOW_DOUBLEBUFFER ((GLenum) 115) +#define GLUT_WINDOW_RGBA ((GLenum) 116) +#define GLUT_WINDOW_PARENT ((GLenum) 117) +#define GLUT_WINDOW_NUM_CHILDREN ((GLenum) 118) +#define GLUT_WINDOW_COLORMAP_SIZE ((GLenum) 119) +#if (GLUT_API_VERSION >= 2) +#define GLUT_WINDOW_NUM_SAMPLES ((GLenum) 120) +#define GLUT_WINDOW_STEREO ((GLenum) 121) +#endif +#if (GLUT_API_VERSION >= 3) +#define GLUT_WINDOW_CURSOR ((GLenum) 122) +#endif +#define GLUT_SCREEN_WIDTH ((GLenum) 200) +#define GLUT_SCREEN_HEIGHT ((GLenum) 201) +#define GLUT_SCREEN_WIDTH_MM ((GLenum) 202) +#define GLUT_SCREEN_HEIGHT_MM ((GLenum) 203) +#define GLUT_MENU_NUM_ITEMS ((GLenum) 300) +#define GLUT_DISPLAY_MODE_POSSIBLE ((GLenum) 400) +#define GLUT_INIT_WINDOW_X ((GLenum) 500) +#define GLUT_INIT_WINDOW_Y ((GLenum) 501) +#define GLUT_INIT_WINDOW_WIDTH ((GLenum) 502) +#define GLUT_INIT_WINDOW_HEIGHT ((GLenum) 503) +#define GLUT_INIT_DISPLAY_MODE ((GLenum) 504) +#if (GLUT_API_VERSION >= 2) +#define GLUT_ELAPSED_TIME ((GLenum) 700) +#endif +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) +#define GLUT_WINDOW_FORMAT_ID ((GLenum) 123) +#endif + +#if (GLUT_API_VERSION >= 2) +/* glutDeviceGet parameters. */ +#define GLUT_HAS_KEYBOARD ((GLenum) 600) +#define GLUT_HAS_MOUSE ((GLenum) 601) +#define GLUT_HAS_SPACEBALL ((GLenum) 602) +#define GLUT_HAS_DIAL_AND_BUTTON_BOX ((GLenum) 603) +#define GLUT_HAS_TABLET ((GLenum) 604) +#define GLUT_NUM_MOUSE_BUTTONS ((GLenum) 605) +#define GLUT_NUM_SPACEBALL_BUTTONS ((GLenum) 606) +#define GLUT_NUM_BUTTON_BOX_BUTTONS ((GLenum) 607) +#define GLUT_NUM_DIALS ((GLenum) 608) +#define GLUT_NUM_TABLET_BUTTONS ((GLenum) 609) +#endif +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) +#define GLUT_DEVICE_IGNORE_KEY_REPEAT ((GLenum) 610) +#define GLUT_DEVICE_KEY_REPEAT ((GLenum) 611) +#define GLUT_HAS_JOYSTICK ((GLenum) 612) +#define GLUT_OWNS_JOYSTICK ((GLenum) 613) +#define GLUT_JOYSTICK_BUTTONS ((GLenum) 614) +#define GLUT_JOYSTICK_AXES ((GLenum) 615) +#define GLUT_JOYSTICK_POLL_RATE ((GLenum) 616) +#endif + +#if (GLUT_API_VERSION >= 3) +/* glutLayerGet parameters. */ +#define GLUT_OVERLAY_POSSIBLE ((GLenum) 800) +#define GLUT_LAYER_IN_USE ((GLenum) 801) +#define GLUT_HAS_OVERLAY ((GLenum) 802) +#define GLUT_TRANSPARENT_INDEX ((GLenum) 803) +#define GLUT_NORMAL_DAMAGED ((GLenum) 804) +#define GLUT_OVERLAY_DAMAGED ((GLenum) 805) + +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +/* glutVideoResizeGet parameters. */ +#define GLUT_VIDEO_RESIZE_POSSIBLE ((GLenum) 900) +#define GLUT_VIDEO_RESIZE_IN_USE ((GLenum) 901) +#define GLUT_VIDEO_RESIZE_X_DELTA ((GLenum) 902) +#define GLUT_VIDEO_RESIZE_Y_DELTA ((GLenum) 903) +#define GLUT_VIDEO_RESIZE_WIDTH_DELTA ((GLenum) 904) +#define GLUT_VIDEO_RESIZE_HEIGHT_DELTA ((GLenum) 905) +#define GLUT_VIDEO_RESIZE_X ((GLenum) 906) +#define GLUT_VIDEO_RESIZE_Y ((GLenum) 907) +#define GLUT_VIDEO_RESIZE_WIDTH ((GLenum) 908) +#define GLUT_VIDEO_RESIZE_HEIGHT ((GLenum) 909) +#endif + +/* glutUseLayer parameters. */ +#define GLUT_NORMAL ((GLenum) 0) +#define GLUT_OVERLAY ((GLenum) 1) + +/* glutGetModifiers return mask. */ +#define GLUT_ACTIVE_SHIFT 1 +#define GLUT_ACTIVE_CTRL 2 +#define GLUT_ACTIVE_ALT 4 + +/* glutSetCursor parameters. */ +/* Basic arrows. */ +#define GLUT_CURSOR_RIGHT_ARROW 0 +#define GLUT_CURSOR_LEFT_ARROW 1 +/* Symbolic cursor shapes. */ +#define GLUT_CURSOR_INFO 2 +#define GLUT_CURSOR_DESTROY 3 +#define GLUT_CURSOR_HELP 4 +#define GLUT_CURSOR_CYCLE 5 +#define GLUT_CURSOR_SPRAY 6 +#define GLUT_CURSOR_WAIT 7 +#define GLUT_CURSOR_TEXT 8 +#define GLUT_CURSOR_CROSSHAIR 9 +/* Directional cursors. */ +#define GLUT_CURSOR_UP_DOWN 10 +#define GLUT_CURSOR_LEFT_RIGHT 11 +/* Sizing cursors. */ +#define GLUT_CURSOR_TOP_SIDE 12 +#define GLUT_CURSOR_BOTTOM_SIDE 13 +#define GLUT_CURSOR_LEFT_SIDE 14 +#define GLUT_CURSOR_RIGHT_SIDE 15 +#define GLUT_CURSOR_TOP_LEFT_CORNER 16 +#define GLUT_CURSOR_TOP_RIGHT_CORNER 17 +#define GLUT_CURSOR_BOTTOM_RIGHT_CORNER 18 +#define GLUT_CURSOR_BOTTOM_LEFT_CORNER 19 +/* Inherit from parent window. */ +#define GLUT_CURSOR_INHERIT 100 +/* Blank cursor. */ +#define GLUT_CURSOR_NONE 101 +/* Fullscreen crosshair (if available). */ +#define GLUT_CURSOR_FULL_CROSSHAIR 102 +#endif + +/* GLUT initialization sub-API. */ +GLUTAPI void APIENTRY glutInit(int *argcp, char **argv); +#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK) +GLUTAPI void APIENTRY __glutInitWithExit(int *argcp, char **argv, void (__cdecl *exitfunc)(int)); +#ifndef GLUT_BUILDING_LIB +static void APIENTRY glutInit_ATEXIT_HACK(int *argcp, char **argv) { __glutInitWithExit(argcp, argv, exit); } +#define glutInit glutInit_ATEXIT_HACK +#endif +#endif +GLUTAPI void APIENTRY glutInitDisplayMode(unsigned int mode); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +GLUTAPI void APIENTRY glutInitDisplayString(const char *string); +#endif +GLUTAPI void APIENTRY glutInitWindowPosition(int x, int y); +GLUTAPI void APIENTRY glutInitWindowSize(int width, int height); +GLUTAPI void APIENTRY glutMainLoop(void); + +/* GLUT window sub-API. */ +GLUTAPI int APIENTRY glutCreateWindow(const char *title); +#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK) +GLUTAPI int APIENTRY __glutCreateWindowWithExit(const char *title, void (__cdecl *exitfunc)(int)); +#ifndef GLUT_BUILDING_LIB +static int APIENTRY glutCreateWindow_ATEXIT_HACK(const char *title) { return __glutCreateWindowWithExit(title, exit); } +#define glutCreateWindow glutCreateWindow_ATEXIT_HACK +#endif +#endif +GLUTAPI int APIENTRY glutCreateSubWindow(int win, int x, int y, int width, int height); +GLUTAPI void APIENTRY glutDestroyWindow(int win); +GLUTAPI void APIENTRY glutPostRedisplay(void); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 11) +GLUTAPI void APIENTRY glutPostWindowRedisplay(int win); +#endif +GLUTAPI void APIENTRY glutSwapBuffers(void); +GLUTAPI int APIENTRY glutGetWindow(void); +GLUTAPI void APIENTRY glutSetWindow(int win); +GLUTAPI void APIENTRY glutSetWindowTitle(const char *title); +GLUTAPI void APIENTRY glutSetIconTitle(const char *title); +GLUTAPI void APIENTRY glutPositionWindow(int x, int y); +GLUTAPI void APIENTRY glutReshapeWindow(int width, int height); +GLUTAPI void APIENTRY glutPopWindow(void); +GLUTAPI void APIENTRY glutPushWindow(void); +GLUTAPI void APIENTRY glutIconifyWindow(void); +GLUTAPI void APIENTRY glutShowWindow(void); +GLUTAPI void APIENTRY glutHideWindow(void); +#if (GLUT_API_VERSION >= 3) +GLUTAPI void APIENTRY glutFullScreen(void); +GLUTAPI void APIENTRY glutSetCursor(int cursor); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +GLUTAPI void APIENTRY glutWarpPointer(int x, int y); +#endif + +/* GLUT overlay sub-API. */ +GLUTAPI void APIENTRY glutEstablishOverlay(void); +GLUTAPI void APIENTRY glutRemoveOverlay(void); +GLUTAPI void APIENTRY glutUseLayer(GLenum layer); +GLUTAPI void APIENTRY glutPostOverlayRedisplay(void); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 11) +GLUTAPI void APIENTRY glutPostWindowOverlayRedisplay(int win); +#endif +GLUTAPI void APIENTRY glutShowOverlay(void); +GLUTAPI void APIENTRY glutHideOverlay(void); +#endif + +/* GLUT menu sub-API. */ +GLUTAPI int APIENTRY glutCreateMenu(void (GLUTCALLBACK *func)(int)); +#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK) +GLUTAPI int APIENTRY __glutCreateMenuWithExit(void (GLUTCALLBACK *func)(int), void (__cdecl *exitfunc)(int)); +#ifndef GLUT_BUILDING_LIB +static int APIENTRY glutCreateMenu_ATEXIT_HACK(void (GLUTCALLBACK *func)(int)) { return __glutCreateMenuWithExit(func, exit); } +#define glutCreateMenu glutCreateMenu_ATEXIT_HACK +#endif +#endif +GLUTAPI void APIENTRY glutDestroyMenu(int menu); +GLUTAPI int APIENTRY glutGetMenu(void); +GLUTAPI void APIENTRY glutSetMenu(int menu); +GLUTAPI void APIENTRY glutAddMenuEntry(const char *label, int value); +GLUTAPI void APIENTRY glutAddSubMenu(const char *label, int submenu); +GLUTAPI void APIENTRY glutChangeToMenuEntry(int item, const char *label, int value); +GLUTAPI void APIENTRY glutChangeToSubMenu(int item, const char *label, int submenu); +GLUTAPI void APIENTRY glutRemoveMenuItem(int item); +GLUTAPI void APIENTRY glutAttachMenu(int button); +GLUTAPI void APIENTRY glutDetachMenu(int button); + +/* GLUT window callback sub-API. */ +GLUTAPI void APIENTRY glutDisplayFunc(void (GLUTCALLBACK *func)(void)); +GLUTAPI void APIENTRY glutReshapeFunc(void (GLUTCALLBACK *func)(int width, int height)); +GLUTAPI void APIENTRY glutKeyboardFunc(void (GLUTCALLBACK *func)(unsigned char key, int x, int y)); +GLUTAPI void APIENTRY glutMouseFunc(void (GLUTCALLBACK *func)(int button, int state, int x, int y)); +GLUTAPI void APIENTRY glutMotionFunc(void (GLUTCALLBACK *func)(int x, int y)); +GLUTAPI void APIENTRY glutPassiveMotionFunc(void (GLUTCALLBACK *func)(int x, int y)); +GLUTAPI void APIENTRY glutEntryFunc(void (GLUTCALLBACK *func)(int state)); +GLUTAPI void APIENTRY glutVisibilityFunc(void (GLUTCALLBACK *func)(int state)); +GLUTAPI void APIENTRY glutIdleFunc(void (GLUTCALLBACK *func)(void)); +GLUTAPI void APIENTRY glutTimerFunc(unsigned int millis, void (GLUTCALLBACK *func)(int value), int value); +GLUTAPI void APIENTRY glutMenuStateFunc(void (GLUTCALLBACK *func)(int state)); +#if (GLUT_API_VERSION >= 2) +GLUTAPI void APIENTRY glutSpecialFunc(void (GLUTCALLBACK *func)(int key, int x, int y)); +GLUTAPI void APIENTRY glutSpaceballMotionFunc(void (GLUTCALLBACK *func)(int x, int y, int z)); +GLUTAPI void APIENTRY glutSpaceballRotateFunc(void (GLUTCALLBACK *func)(int x, int y, int z)); +GLUTAPI void APIENTRY glutSpaceballButtonFunc(void (GLUTCALLBACK *func)(int button, int state)); +GLUTAPI void APIENTRY glutButtonBoxFunc(void (GLUTCALLBACK *func)(int button, int state)); +GLUTAPI void APIENTRY glutDialsFunc(void (GLUTCALLBACK *func)(int dial, int value)); +GLUTAPI void APIENTRY glutTabletMotionFunc(void (GLUTCALLBACK *func)(int x, int y)); +GLUTAPI void APIENTRY glutTabletButtonFunc(void (GLUTCALLBACK *func)(int button, int state, int x, int y)); +#if (GLUT_API_VERSION >= 3) +GLUTAPI void APIENTRY glutMenuStatusFunc(void (GLUTCALLBACK *func)(int status, int x, int y)); +GLUTAPI void APIENTRY glutOverlayDisplayFunc(void (GLUTCALLBACK *func)(void)); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +GLUTAPI void APIENTRY glutWindowStatusFunc(void (GLUTCALLBACK *func)(int state)); +#endif +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) +GLUTAPI void APIENTRY glutKeyboardUpFunc(void (GLUTCALLBACK *func)(unsigned char key, int x, int y)); +GLUTAPI void APIENTRY glutSpecialUpFunc(void (GLUTCALLBACK *func)(int key, int x, int y)); +GLUTAPI void APIENTRY glutJoystickFunc(void (GLUTCALLBACK *func)(unsigned int buttonMask, int x, int y, int z), int pollInterval); +#endif +#endif +#endif + +/* GLUT color index sub-API. */ +GLUTAPI void APIENTRY glutSetColor(int, GLfloat red, GLfloat green, GLfloat blue); +GLUTAPI GLfloat APIENTRY glutGetColor(int ndx, int component); +GLUTAPI void APIENTRY glutCopyColormap(int win); + +/* GLUT state retrieval sub-API. */ +GLUTAPI int APIENTRY glutGet(GLenum type); +GLUTAPI int APIENTRY glutDeviceGet(GLenum type); +#if (GLUT_API_VERSION >= 2) +/* GLUT extension support sub-API */ +GLUTAPI int APIENTRY glutExtensionSupported(const char *name); +#endif +#if (GLUT_API_VERSION >= 3) +GLUTAPI int APIENTRY glutGetModifiers(void); +GLUTAPI int APIENTRY glutLayerGet(GLenum type); +#endif + +/* GLUT font sub-API */ +GLUTAPI void APIENTRY glutBitmapCharacter(void *font, int character); +GLUTAPI int APIENTRY glutBitmapWidth(void *font, int character); +GLUTAPI void APIENTRY glutStrokeCharacter(void *font, int character); +GLUTAPI int APIENTRY glutStrokeWidth(void *font, int character); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +GLUTAPI int APIENTRY glutBitmapLength(void *font, const unsigned char *string); +GLUTAPI int APIENTRY glutStrokeLength(void *font, const unsigned char *string); +#endif + +/* GLUT pre-built models sub-API */ +GLUTAPI void APIENTRY glutWireSphere(GLdouble radius, GLint slices, GLint stacks); +GLUTAPI void APIENTRY glutSolidSphere(GLdouble radius, GLint slices, GLint stacks); +GLUTAPI void APIENTRY glutWireCone(GLdouble base, GLdouble height, GLint slices, GLint stacks); +GLUTAPI void APIENTRY glutSolidCone(GLdouble base, GLdouble height, GLint slices, GLint stacks); +GLUTAPI void APIENTRY glutWireCube(GLdouble size); +GLUTAPI void APIENTRY glutSolidCube(GLdouble size); +GLUTAPI void APIENTRY glutWireTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings); +GLUTAPI void APIENTRY glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings); +GLUTAPI void APIENTRY glutWireDodecahedron(void); +GLUTAPI void APIENTRY glutSolidDodecahedron(void); +GLUTAPI void APIENTRY glutWireTeapot(GLdouble size); +GLUTAPI void APIENTRY glutSolidTeapot(GLdouble size); +GLUTAPI void APIENTRY glutWireOctahedron(void); +GLUTAPI void APIENTRY glutSolidOctahedron(void); +GLUTAPI void APIENTRY glutWireTetrahedron(void); +GLUTAPI void APIENTRY glutSolidTetrahedron(void); +GLUTAPI void APIENTRY glutWireIcosahedron(void); +GLUTAPI void APIENTRY glutSolidIcosahedron(void); + +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +/* GLUT video resize sub-API. */ +GLUTAPI int APIENTRY glutVideoResizeGet(GLenum param); +GLUTAPI void APIENTRY glutSetupVideoResizing(void); +GLUTAPI void APIENTRY glutStopVideoResizing(void); +GLUTAPI void APIENTRY glutVideoResize(int x, int y, int width, int height); +GLUTAPI void APIENTRY glutVideoPan(int x, int y, int width, int height); + +/* GLUT debugging sub-API. */ +GLUTAPI void APIENTRY glutReportErrors(void); +#endif + +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) +/* GLUT device control sub-API. */ +/* glutSetKeyRepeat modes. */ +#define GLUT_KEY_REPEAT_OFF 0 +#define GLUT_KEY_REPEAT_ON 1 +#define GLUT_KEY_REPEAT_DEFAULT 2 + +/* Joystick button masks. */ +#define GLUT_JOYSTICK_BUTTON_A 1 +#define GLUT_JOYSTICK_BUTTON_B 2 +#define GLUT_JOYSTICK_BUTTON_C 4 +#define GLUT_JOYSTICK_BUTTON_D 8 + +GLUTAPI void APIENTRY glutIgnoreKeyRepeat(int ignore); +GLUTAPI void APIENTRY glutSetKeyRepeat(int repeatMode); +GLUTAPI void APIENTRY glutForceJoystickFunc(void); + +/* GLUT game mode sub-API. */ +/* glutGameModeGet. */ +#define GLUT_GAME_MODE_ACTIVE ((GLenum) 0) +#define GLUT_GAME_MODE_POSSIBLE ((GLenum) 1) +#define GLUT_GAME_MODE_WIDTH ((GLenum) 2) +#define GLUT_GAME_MODE_HEIGHT ((GLenum) 3) +#define GLUT_GAME_MODE_PIXEL_DEPTH ((GLenum) 4) +#define GLUT_GAME_MODE_REFRESH_RATE ((GLenum) 5) +#define GLUT_GAME_MODE_DISPLAY_CHANGED ((GLenum) 6) + +GLUTAPI void APIENTRY glutGameModeString(const char *string); +GLUTAPI int APIENTRY glutEnterGameMode(void); +GLUTAPI void APIENTRY glutLeaveGameMode(void); +GLUTAPI int APIENTRY glutGameModeGet(GLenum mode); +#endif + +#ifdef __cplusplus +} + +#endif + +#ifdef GLUT_APIENTRY_DEFINED +# undef GLUT_APIENTRY_DEFINED +# undef APIENTRY +#endif + +#ifdef GLUT_WINGDIAPI_DEFINED +# undef GLUT_WINGDIAPI_DEFINED +# undef WINGDIAPI +#endif + +#ifdef GLUT_DEFINED___CDECL +# undef GLUT_DEFINED___CDECL +# undef __cdecl +#endif + +#ifdef GLUT_DEFINED__CRTIMP +# undef GLUT_DEFINED__CRTIMP +# undef _CRTIMP +#endif + +#endif /* __glut_h__ */ diff --git a/samples/glut/README-win32.txt b/samples/glut/README-win32.txt index 5e22e9789..f3c1cbaa5 100644 --- a/samples/glut/README-win32.txt +++ b/samples/glut/README-win32.txt @@ -1,613 +1,613 @@ - - - GLUT for Win32 README - --------------------- - - -VERSION/INFO: - - This is GLUT for Win32 version 3.7.6 as of Nov 8th 2001. - See the COPYRIGHT section for distribution and copyright notices. - Send all bug reports and questions for this version of GLUT to - Nate Robins [nate@pobox.com]. - - For more information about GLUT for Win32, see the web page: - www.pobox.com/~nate/glut.html or subscribe to the GLUT for Win32 - mailing list by sending e-mail to majordomo@perp.com with - "subscribe glut" in the body of the message. - - For general information about GLUT, see the GLUT web page: - http://reality.sgi.com/opengl/glut3/glut3.html and be sure to - check the GLUT FAQ first for any questions that you may have: - http://reality.sgi.com/opengl/glut3/glut-faq.html - - -COMPILING/INSTALLATION: - - o Precompiled versions of the DLL and import library can be - found on the GLUT for Win32 web page mentioned above. - - o Microsoft Developer Studio 6 workspace and project files have - been included in the source code distribution. - - To build the glut dll: - First, open Microsoft Developer Studio. - Then, select File -> Open Workspace and find the glut.dsw file - in the file dialog and double-click on it. - Finally, select Build -> Build glut32.dll. - When the build is finished, it will copy: - glut32.dll to %WinDir%\System, - glut32.lib to $(MSDevDir)\..\..\VC98\lib, and - glut.h to $(MSDevDir)\..\..\VC98\include\GL. - - Additional workspace files have been included in the progs, test - and lib directories to build the progs, tests and libs respectively. - - -BORLAND NOTES: - - From what I understand, Borland supplies a utility that - converts Microsoft Visual C++ .libs into Borland compatible - files. Therefore, the best method for Borland users is - probably to get the precompiled versions of the library and - convert the library. To create an import library for Borland - from the DLLs, use the following command (from a command prompt): - IMPLIB glut32.lib glut32.dll - If IMPLIB crashes when called this way, try - IMPLIB glut32.lib glut32.def - using the glut32.def file in this distribution. - - -FORTRAN NOTES: - - Bill Mitchell [william.mitchell@nist.gov] has put considerable - effort into getting GLUT to work with different compilers for - Fortran 90. He indicates that you should copy the f90glut.h - file to your $(MSDevDir)\..\..\VC98\include\GL directory. - Then, just build GLUT as usual. The Fortran 90 interface, f90gl, - can be obtained at http://math.nist.gov/f90gl and contains - installation instructions and usage examples. - - -MISC NOTES: - - o Overlay support is not implemented, nor are there any plans to - implement it in the near future. - - o To customize the windows icon, you can use the resource name - GLUT_ICON. For example, create an icon named "glut.ico", and - create a file called glut.rc that contains the following: - GLUT_ICON ICON glut.ico - then compile the glut.rc file with the following: - rc /r glut - and link the resulting glut.res file into your executable - (just like you would an object file). - Alternatively, you can simply add the glut.rc file to your - project if you are using Microsoft Developer Studio. - - -IMPLEMENTATION DEPENDENT DIFFERENCES: - - There are a few differences between the Win32 version of GLUT - and the X11 version of GLUT. Those are outlined here. Note - that MOST of these differences are allowed by the GLUT - specification. Bugs and unsupported features are outlined in - the UNSUPPORTED/BUGS section. - - o glutInit: - The following command line options have no meaning (and are - ignored) in GLUT for Win32: - -display, -indirect, -direct, -sync. - - o glutInitWindowPosition, glutPositionWindow: - Win32 has two different coordinate systems for windows. - One is in terms of client space and the other is the whole - window space (including the decorations). If you - glutPositionWindow(0, 0), GLUT for Win32 will place the - window CLIENT area at 0, 0. This will cause the window - decorations (title bar and left edge) to be OFF-SCREEN, but - it gives the user the most flexibility in positioning. - HOWEVER, if the user specifies glutInitWindowPosition(0, 0), - the window is placed relative to window space at 0, 0. - This will cause the window to be opened in the upper left - corner with all the decorations showing. This behaviour is - acceptable under the current GLUT specification. - - o glutSetIconTitle, glutSetWindowTitle: - There is no separation between Icon title and Window title - in Win32. Therefore, setting an icon title in Win32 has - no effect. - - o glutSetCursor: - As indicated in the GLUT specification, cursors may be - different on different platforms. This is the case in GLUT - for Win32. For the most part, the cursors will match the - meaning, but not necessarily the shape. Notable exceptions - are the GLUT_CURSOR_INFO & GLUT_CURSOR_SPRAY which use the - crosshair cursor and the GLUT_CURSOR_CYCLE which uses the - 'no' or 'destroy' cursor in Win32. - - o glutVisibilityFunc: - Win32 seems to be unable to determine if a window is fully - obscured. Therefore, the visibility of a GLUT window is - only reflected by its Iconic, Hidden or Shown state. That - is, even if a window is fully obscured, in GLUT for Win32, - it is still "visible". - - o glutEntryFunc: - Window Focus is handled differently in Win32 and X. - Specifically, the "window manager" in Win32 uses a "click to - focus" policy. That is, in order for a window to receive - focus, a mouse button must be clicked in it. Likewise, in - order for a window to lose focus, a mouse button must be - clicked outside the window (or in another window). - Therefore, the Enter and Leave notification provided by GLUT - may behave differently in the Win32 and in X11 versions. - There is a viable workaround for this. A program called - "Tweak UI" is provided by Microsoft which can be used to - change the focus policy in Win32 to "focus follows mouse". - It is available from the Microsoft Web Pages: - http://www.microsoft.com/windows/software/PowerToy.htm - - o glutCopyColormap: - GLUT for Win32 always copies the colormap. There is never - any sharing of colormaps. This is probably okay, since - Win32 merges the logical palette and the physical palette - anyway, so even if there are two windows with totally - different colors in their colormaps, Win32 will find a - (hopefully) good match between them. - - o glutIdleFunc + menus: - The glut idle function will NOT be called when a menu is - active. This causes all animation to stop when a menu is - active (in general, this is probably okay). Timer - functions will still fire, however. If the timer callback - draws into the rendering context, the drawing will not show - up until after the menu has finished, though. - - -UNSUPPORTED/BUGS: - - o glutAttachMenu: - Win32 only likes to work with left and right mouse buttons. - Especially so with popup menus. Therefore, when attaching - the menu to the middle mouse button, the LEFT mouse button - must be used to select from the menu. - - o glutSpaceball*, glutButtonBox*, glutTablet*, glutDials*: - None of the special input devices are supported at this - time. - - o When resizing or moving a GLUT for Win32 window, no updating - is performed. This causes the window to leave "tracks" on - the screen when getting bigger or when previously obscured - parts are being revealed. I put in a bit of a kludgy - workaround for those that absolutely can't have the weird - lines. The reshape callback is called multiple times for - reshapes. Therefore, in the reshape callback, some drawing - can be done. It should probably be limited to a color buffer - clear. - - o The video resizing capabilities of GLUT 3.3+ for X11 is - currently unimplemented (this is probably ok, since it - really isn't part of the spec until 4.0). I doubt that - this will ever be part of GLUT for Win32, since there is no - hardware to support it. A hack could simply change the - resolution of the desktop. - - -CHANGES/FIXES: - - (Nov 8, '01) - x Released 3.7.6 - - (Nov 8, '01) - x Changed fullscreen mode from TOPMOST back to simply TOP, since - (it turns out) many people use windows atop a GLUT window. - - (Nov 8, '01) - x Added code to prevent CPU spiking when no idle function is - registered. Otherwise, if an idle function is registered, spike - CPU so that the idle function gets all the attention it needs and - if this is a problem on the program side, the user can stick a - sleep() in their idle function. I believe that this strikes the - best balance betweeen GLUT being fast, and also being "nice" to - other processes. Thanks to James Wright for reporting this bug. - - (Nov 8, '01) - x Fixed bug in motion callback handler which wasn't setting the - current window, so multiple window apps (e.g., any GLUI app) - wouldn't get the callback correctly. - - (Oct 4, '01) - x Fixed bug in glutEnterGameMode() that caused new windows to not - be in "fullscreen" mode, so they got window decorations. - - (Oct 4, '01) - x Fixed bug in glutEnterGameMode() that caused new windows to not - be in "fullscreen" mode, so they got window decorations. - - (Oct 3, '01) - x Fixed bug in getVisualInfoFromString(): visuals not reloaded on - display mode change. Reload visuals each time they are queried. - This fixes a problem with Win32 because the list of availabe Visuals - (Pixelformats) changes after a change in displaymode. The problem - occurs when switching to gamemode and back. Thanks to Michael - Wimmer for pointing this out & providing the fix. - - (Oct 3, '01) - x Fixed bug in XGetVisualInfo(): pixelformats enumerated incorrectly. - Passing 0 as a pixelformat index to DescribePixelFormat gives - unpredictible results (e.g., this fails on the Voodoo opengl32.dll - and always reports 0 as the last available pixelformat index). - Thanks to Michael Wimmer for pointing this out & providing the fix. - - (Oct 3, '01) - x Fixed bug in glXGetConfig(): pixelformats enumerated incorrectly. The - test was OpenGL support OR draw to window, but should be AND. Thanks - to Michael Wimmer for pointing this out & providing the fix. - - (Sep 28, '01) - x Fixed glutChangeToSubMenu()/glutChangeToMenuEntry() bug where if you - went back and forth between a submenu and a plain entry, the submenu - wouldn't be updated properly. - - (Sep 28, '01) - x glutSetIconTitle() is now a nop. - - (Sep 28, '01) - x glutFullScreen() now sets the window as TOPMOST, therefore, the - window will always be on top (this essentially disables alt-tabbing). - - (Sep 28, '01) - x The key repeat ignore flag is now honored correctly. - - (Sep 28, '01) - x Key presses are now reported more accurately and fully, in - particular, modified up events (i.e., SHIFT-2) are now reported - correctly. - - (Sep 28, '01) - x Subwindows nested arbitrarily deep get their keyboard callbacks - correctly now. - - (Sep 28, '01) - x Major rewrite of the window procedure code to clean it up and make - way for other bug fixes. - - (Sep 23, '01) - x Fixed noof example program to use RAND_MAX instead of assumed - max of 2147483647.0. (Now it looks _much_ better!) - - (Sep 22, '01) - x Fixed sunlight example program. globe.raw data file was corrupt, - added a new one. - - (Sep 22, '01) - x Fixed zcomposite example program to print message if overlay - support is not found (instead of crashing). - - (Jan 22, '01) - x Fixed malloc(0) bug in Win32 version of XGetVisualInfo. Thanks - to Kekoa Proudfoot for bringing this to my attention. - - (Dec 12, '00) - x Added data files for the advanced & advanced97 programs. - - (Dec 12, '00) - x Added Developer Studio 6 project and workspace files for pretty - much everything (the stuff left out was usually unix specific). - - (Dec 7, '00) - x Fixed several compilation problems & corrupt files. Thanks to - Alexander Stohr for bringing these to my attention and providing - detailed fixes. - - (Dec 6, '00) - x Fixed compiler support for lcc. Thanks to Gordon for bringing - this to my attention and debugging fixes. - - (Nov 8, '00) - x Fixed submenu problem (sometimes the menu callback was not - called for valid items). Thanks to Michael Keeley. - - (Oct 16, '00) - x Corrected corrupt duck.iv file. Thanks to Jon Willeke for finding - this problem. - - (Sept 27, '00) - x Fixed bug in processWorkList that could cause a hang. Thanks to - Bill Volz & Daniel Azuma. - - (Sept 26, '00) - x Added mui DLL project file (thanks to DMWeldy@ugsolutions.com). - - (Sept 9, '00) - x Fixed Delete key bug (crash when no keyboard callback was - registered, but a special key callback was). Thanks to - Kent Bowling (kent_bowling@hotmail.com) for finding this bug. - - (May 18, '00) - x Fixed subwindow keyboard callbacks. - - (May 22, '97) - o Menus don't work under Windows 95 - x Fixed! Added a unique identifier to each menu item, and a - search function to grab a menu item given the unique identifier. - - (May 21, '97) - o A few minor bug fixes here and there. - x Thanks to Bruce Silberman and Chris Vale for their help with - this. We now have a DLL! - - (Apr 25, '97) - o DLL version of the library is coming (as soon as I figure out - how to do it -- if you know, let me know). - x Thanks to Bruce Silberman and Chris Vale for their help with - this. We now have a DLL! - - (Apr 24, '97) - x Added returns to KEY_DOWN etc messages so that the F10 key - doesn't toggle the system menu anymore. - - (Apr 7, '97) - o Palette is incorrect for modes other than TrueColor. - x Fixed this by forcing a default palette in modes that aren't - Truecolor in order to 'simulate' it. The applications - program shouldn't have to do this IMHO, but I guess we - can't argue with Microsoft (well, we can, but what good - will it do?). - - (Apr 2, '97) - x Added glut.ide file for Borland users. - - (Apr 2, '97) - x Fixed a bug in the WM_QUERYNEWPALETTE message. Wasn't - checking for a null colormap, then de-ref'd it. Oops. - - (Mar 13, '97) - o glutTimerFunc: - Currently, GLUT for Win32 programs busy waits when there is - an outstanding timer event (i.e., there is no select() - call). I haven't found this to be a problem, but I plan to - fix it just because I can't bear the thought of a busy wait. - x Added a timer event and a wait in the main loop. This fixes - the CPU spike. - - (Mar 11, '97) - x Fixed subwindow visibility. The visibility callback of - subwindows wasn't being called, now it is. - - (Mar 11, '97) - o glutGetHDC, glutGetHWND: - In order to support additional dialog boxes, wgl fonts, and - a host of other Win32 dependent structures, two functions - have been added that operate on the current window in GLUT. - The first (glutGetHDC) returns a handle to the current - windows device context. The second (glutGetHWND) returns - handle to the current window. - x Took these out to preserve GLUT portability. - - (Mar 11, '97) - x Fixed the glutWarpPointer() coordinates. Were relative to - the screen, now relative to window (client area) origin - (which is what they're supposed to be). - - (Mar 11, '97) - o glutCreateMenu, glutIdleFunc: - Menu's are modal in Win32. That is, they don't allow any - messages to be processed while they are up. Therefore, if - an idle function exists, it will not be called while - processing a menu. - x Fixed! I've put in a timer function that fires every - millisecond while a menu is up. The timer function handles - idle and timer events only (which should be the only - functions that are firing when a menu is up anyway). - - (Mar 7 '97) - x Fixed minor bugs tracked down by the example programs. - - (Mar 6, '97) - x Merged 3.3 GLUT for X11 into 3.2 GLUT for Win32. New code - structure allows for EASY merging! - - o In Win32, the parent gets the right to set the cursor of - any of its children. Therefore, a child windows cursor - will 'blink' between its cursor and its parent. - x Fixed this by checking whether the cursor is in a child - window or not. - - (Feb 28 '97) - o On initial bringup apps are getting 2 display callbacks. - x Fixed by the Fev 28 re-write. - - o Some multiple window (not subwindow) functionality is messed up. - See the sphere.exe program. - x Fixed by the Feb 28 re-write. - - o GLUT for Win32 supports color index mode ONLY in a paletted - display mode (i.e., 256 or 16 color mode). - x Fixed this in the re-write. If you can get a color index - visual (pixel format) you can use color index mode. - - (Feb 28 '97) - o Quite a few bugs (and incompatibilities) were being caused - by the structure that I used in the previous port of GLUT. - Therefore I decided that it would be best to "get back to - the roots". I re-implemented most of glut trying to stick - with the structure layed out by Mark. The result is a much - more stable version that passes ALL (!) (except overlay) - the tests provided by Mark. In addition, this new - structure will allow future enhancements by Mark to be - integrated much more quickly into the Win32 version. Also, - I'm now ordering the bugs in reverse, so that the most - recently fixed appear at the top of the list. - - (9/8/96) - o Changed the glutGetModifiers code to produce an error if not - called in the core input callbacks. - - (9/11/96) - o If the alt key is pressed with more than one other modifier key - it acts as if it is stuck -- it stays selected until pressed - and released again. - x Fixed. - - (9/12/96) - o When a submenu is attached to a menu, sometimes a GPF occurs. - Fixed. Needed to set the submenu before referencing it's members. - - o Kenny: Also, one little problem, I attached the menu to the - right-button, but when the left-button is pressed I detach - it to give the right-button new meaning; if I pop-up the menu and I - don't want to select anything, like most users, I click off of the - menu to make it disappear. When I do this, I get a GLUT error and - the program terminates because I am altering the menu attachment - from within the button press while the menu is active. - x Fixed. Needed to finish the menu when the user presses the button, - not just when a button is released. - - o GLUT for Win32 emulates a middle mouse button by checking if - both mouse buttons are down. This causes a lot of problems with - the menu and other multiple mouse button things. - x Fixed. No more middle mouse button emulation. Perhaps it would - be a good idea to emulate the middle mouse button (if not present) - with a key? - - (9/15/96) - o Added code to accept a user defined icon. If no icon is provided, - a default icon is loaded. - - (9/19/96) - o Shane: Command line options seem to be screwed up. (9/13) - x Fixed. The geometry command line was broken, and so was the - gldebug command line. - - o Fixed a bug in the default glut reshape. It was looking for the - parent of the current window and GPF'ing if there wasn't a parent. - Put in a check for a parent, and if none is there, use the - child. - - o Idle function sucks up all processor cycles. (9/8/96) - x I don't know if this is avoidable. If you have a tight rendering - loop, it may be that the processor time is going to be sucked up - no matter what. You can add a sleep() to the end of your render - loop if you would like to yeild to other processes and you don't - care too much about the speed of your rendering loop. If you have - Hardware that supports OpenGL (like a 3Dpro card, or GLint card) - then this should be less of a problem, since it won't be rendering - in software. (9/11/96) - - o If a window is fully obscured by another window, the visibility - callback is NOT called. As far as I can tell, this is a limitation - of the Win32 api, but a workaround is being searched for. (9/8/96) - x Limitation of the Win32 API - - o Fixed the entry functions. They only work if the keyboard focus - changes. Therefore, in most Win32 systems, the mouse must be - pressed outside of the window to get a GLUT_LEFT message and - then pressed inside the window for a GLUT_ENTERED message. - - o Alt modifier key doesn't work with keyboard callback. (9/8/96) - x Probably okay, because the glut spec says that these keys can - be intercepted by the system (which the alt key is...) (9/11/96) - - (11/17/96) - o glutRemoveMenuItem() not working properly. - x Thanks to Gary (grc@maple.civeng.rutgers.edu) for the fix to - this one. - - o Timer functions are messed up. - x Thanks to Joseph Galbraith for the fix to this one. - - (12/9/96) - o One (minor) difference came up between the X version of glut - and the nt one which you should know about. It is not a new - problem, and it concerns co-ords returned to the pointer - callbacks. (glutMotionFunc, glutMouseFunc) - Under X, you get co-ords in the range 0 +/- 2^15, under NT - you get 0..2^16. This is only really a problem when moving - above or to the left of the window. - eg dragging one pixel ABOVE the window will give :- - under x11 : y = -1 - under nt : y = 2^16 -1 - x Put in fix provided by Shane Clauson. - - (12/17/96) - o Idle functions not working properly for multiple windows. - x Fixed this by posting an idle message to every window in the - window list when idle. - - (12/18/96) - o glutSetCursor() was misbehaving (lthomas@cco.caltech.edu). - x Win32 requires that the hCursor member of the window class - be set to NULL when the class is registered or whenever the - mouse is moved, the original cursor is replaced (go - figure!). Now sets the cursor whenever a WM_MOUSEMOVE message - is received, because the WM_SETCURSOR event resets the cursor - even when in the decoration area. - - o Geometry is not being handled quite right. The numbers don't - take into account the window decorations. That is, if I say - make a window 100x100, then the WHOLE window (not just the - client area) is 100x100. Therefore, the client (opengl) area - is smaller than 100x100. (9/8/96) - x Fixed. Added code to subtract the decoration size on glutGet() - and add the decoration size on glutReshapeWindow(). - - o Multiple glutPostRedisplay() calls are NOT being combined. - To get round the "coalesce" problem on glutPostRedisplay, - the easiest solution is to roll-your-own coalesce by - keeping a global "dirty" flag in the app (eg replace all - calls to glutPostRedisplay with image_dirty=TRUE;), and to - handle image_dirty with a single glutPostRedisplay in the - idle callback when required. (erk - but increases - performance for my particular app (a rendering engine on - the end of a pipleine with a stream of graphics updates) by - a couple of orders of magnitude ! ) (9/8/96) - x Added code to coalesce redisplays. Every idle cycle, a - check is made to see which windows need redisplay, if they - need it, a redisplay is posted. The glutPostRedisplay() - call is just a stub that sets a flag. - - -THANKS: - - Special thanks to the following people for extensive testing, - suggestions, fixes and help: - - Alexander Stohr - Shane Clauson - Kenny Hoff - Richard Readings - Paul McQuesten - Philip Winston - JaeWoo Ahn - Joseph Galbraith - Paula Higgins - Sam Fortin - Chris Vale - Bill Mitchell - - and of course, the original author of GLUT: - Mark Kilgard. - - and many others... - - -COPYRIGHT: - -The OpenGL Utility Toolkit distribution for Win32 (Windows NT & -Windows 95) contains source code modified from the original source -code for GLUT version 3.3 which was developed by Mark J. Kilgard. The -original source code for GLUT is Copyright 1997 by Mark J. Kilgard. -GLUT for Win32 is Copyright 1997 by Nate Robins and is not in the -public domain, but it is freely distributable without licensing fees. -It is provided without guarantee or warrantee expressed or implied. -It was ported with the permission of Mark J. Kilgard by Nate Robins. - -THIS SOURCE CODE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER -EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - -OpenGL (R) is a registered trademark of Silicon Graphics, Inc. + + + GLUT for Win32 README + --------------------- + + +VERSION/INFO: + + This is GLUT for Win32 version 3.7.6 as of Nov 8th 2001. + See the COPYRIGHT section for distribution and copyright notices. + Send all bug reports and questions for this version of GLUT to + Nate Robins [nate@pobox.com]. + + For more information about GLUT for Win32, see the web page: + www.pobox.com/~nate/glut.html or subscribe to the GLUT for Win32 + mailing list by sending e-mail to majordomo@perp.com with + "subscribe glut" in the body of the message. + + For general information about GLUT, see the GLUT web page: + http://reality.sgi.com/opengl/glut3/glut3.html and be sure to + check the GLUT FAQ first for any questions that you may have: + http://reality.sgi.com/opengl/glut3/glut-faq.html + + +COMPILING/INSTALLATION: + + o Precompiled versions of the DLL and import library can be + found on the GLUT for Win32 web page mentioned above. + + o Microsoft Developer Studio 6 workspace and project files have + been included in the source code distribution. + + To build the glut dll: + First, open Microsoft Developer Studio. + Then, select File -> Open Workspace and find the glut.dsw file + in the file dialog and double-click on it. + Finally, select Build -> Build glut32.dll. + When the build is finished, it will copy: + glut32.dll to %WinDir%\System, + glut32.lib to $(MSDevDir)\..\..\VC98\lib, and + glut.h to $(MSDevDir)\..\..\VC98\include\GL. + + Additional workspace files have been included in the progs, test + and lib directories to build the progs, tests and libs respectively. + + +BORLAND NOTES: + + From what I understand, Borland supplies a utility that + converts Microsoft Visual C++ .libs into Borland compatible + files. Therefore, the best method for Borland users is + probably to get the precompiled versions of the library and + convert the library. To create an import library for Borland + from the DLLs, use the following command (from a command prompt): + IMPLIB glut32.lib glut32.dll + If IMPLIB crashes when called this way, try + IMPLIB glut32.lib glut32.def + using the glut32.def file in this distribution. + + +FORTRAN NOTES: + + Bill Mitchell [william.mitchell@nist.gov] has put considerable + effort into getting GLUT to work with different compilers for + Fortran 90. He indicates that you should copy the f90glut.h + file to your $(MSDevDir)\..\..\VC98\include\GL directory. + Then, just build GLUT as usual. The Fortran 90 interface, f90gl, + can be obtained at http://math.nist.gov/f90gl and contains + installation instructions and usage examples. + + +MISC NOTES: + + o Overlay support is not implemented, nor are there any plans to + implement it in the near future. + + o To customize the windows icon, you can use the resource name + GLUT_ICON. For example, create an icon named "glut.ico", and + create a file called glut.rc that contains the following: + GLUT_ICON ICON glut.ico + then compile the glut.rc file with the following: + rc /r glut + and link the resulting glut.res file into your executable + (just like you would an object file). + Alternatively, you can simply add the glut.rc file to your + project if you are using Microsoft Developer Studio. + + +IMPLEMENTATION DEPENDENT DIFFERENCES: + + There are a few differences between the Win32 version of GLUT + and the X11 version of GLUT. Those are outlined here. Note + that MOST of these differences are allowed by the GLUT + specification. Bugs and unsupported features are outlined in + the UNSUPPORTED/BUGS section. + + o glutInit: + The following command line options have no meaning (and are + ignored) in GLUT for Win32: + -display, -indirect, -direct, -sync. + + o glutInitWindowPosition, glutPositionWindow: + Win32 has two different coordinate systems for windows. + One is in terms of client space and the other is the whole + window space (including the decorations). If you + glutPositionWindow(0, 0), GLUT for Win32 will place the + window CLIENT area at 0, 0. This will cause the window + decorations (title bar and left edge) to be OFF-SCREEN, but + it gives the user the most flexibility in positioning. + HOWEVER, if the user specifies glutInitWindowPosition(0, 0), + the window is placed relative to window space at 0, 0. + This will cause the window to be opened in the upper left + corner with all the decorations showing. This behaviour is + acceptable under the current GLUT specification. + + o glutSetIconTitle, glutSetWindowTitle: + There is no separation between Icon title and Window title + in Win32. Therefore, setting an icon title in Win32 has + no effect. + + o glutSetCursor: + As indicated in the GLUT specification, cursors may be + different on different platforms. This is the case in GLUT + for Win32. For the most part, the cursors will match the + meaning, but not necessarily the shape. Notable exceptions + are the GLUT_CURSOR_INFO & GLUT_CURSOR_SPRAY which use the + crosshair cursor and the GLUT_CURSOR_CYCLE which uses the + 'no' or 'destroy' cursor in Win32. + + o glutVisibilityFunc: + Win32 seems to be unable to determine if a window is fully + obscured. Therefore, the visibility of a GLUT window is + only reflected by its Iconic, Hidden or Shown state. That + is, even if a window is fully obscured, in GLUT for Win32, + it is still "visible". + + o glutEntryFunc: + Window Focus is handled differently in Win32 and X. + Specifically, the "window manager" in Win32 uses a "click to + focus" policy. That is, in order for a window to receive + focus, a mouse button must be clicked in it. Likewise, in + order for a window to lose focus, a mouse button must be + clicked outside the window (or in another window). + Therefore, the Enter and Leave notification provided by GLUT + may behave differently in the Win32 and in X11 versions. + There is a viable workaround for this. A program called + "Tweak UI" is provided by Microsoft which can be used to + change the focus policy in Win32 to "focus follows mouse". + It is available from the Microsoft Web Pages: + http://www.microsoft.com/windows/software/PowerToy.htm + + o glutCopyColormap: + GLUT for Win32 always copies the colormap. There is never + any sharing of colormaps. This is probably okay, since + Win32 merges the logical palette and the physical palette + anyway, so even if there are two windows with totally + different colors in their colormaps, Win32 will find a + (hopefully) good match between them. + + o glutIdleFunc + menus: + The glut idle function will NOT be called when a menu is + active. This causes all animation to stop when a menu is + active (in general, this is probably okay). Timer + functions will still fire, however. If the timer callback + draws into the rendering context, the drawing will not show + up until after the menu has finished, though. + + +UNSUPPORTED/BUGS: + + o glutAttachMenu: + Win32 only likes to work with left and right mouse buttons. + Especially so with popup menus. Therefore, when attaching + the menu to the middle mouse button, the LEFT mouse button + must be used to select from the menu. + + o glutSpaceball*, glutButtonBox*, glutTablet*, glutDials*: + None of the special input devices are supported at this + time. + + o When resizing or moving a GLUT for Win32 window, no updating + is performed. This causes the window to leave "tracks" on + the screen when getting bigger or when previously obscured + parts are being revealed. I put in a bit of a kludgy + workaround for those that absolutely can't have the weird + lines. The reshape callback is called multiple times for + reshapes. Therefore, in the reshape callback, some drawing + can be done. It should probably be limited to a color buffer + clear. + + o The video resizing capabilities of GLUT 3.3+ for X11 is + currently unimplemented (this is probably ok, since it + really isn't part of the spec until 4.0). I doubt that + this will ever be part of GLUT for Win32, since there is no + hardware to support it. A hack could simply change the + resolution of the desktop. + + +CHANGES/FIXES: + + (Nov 8, '01) + x Released 3.7.6 + + (Nov 8, '01) + x Changed fullscreen mode from TOPMOST back to simply TOP, since + (it turns out) many people use windows atop a GLUT window. + + (Nov 8, '01) + x Added code to prevent CPU spiking when no idle function is + registered. Otherwise, if an idle function is registered, spike + CPU so that the idle function gets all the attention it needs and + if this is a problem on the program side, the user can stick a + sleep() in their idle function. I believe that this strikes the + best balance betweeen GLUT being fast, and also being "nice" to + other processes. Thanks to James Wright for reporting this bug. + + (Nov 8, '01) + x Fixed bug in motion callback handler which wasn't setting the + current window, so multiple window apps (e.g., any GLUI app) + wouldn't get the callback correctly. + + (Oct 4, '01) + x Fixed bug in glutEnterGameMode() that caused new windows to not + be in "fullscreen" mode, so they got window decorations. + + (Oct 4, '01) + x Fixed bug in glutEnterGameMode() that caused new windows to not + be in "fullscreen" mode, so they got window decorations. + + (Oct 3, '01) + x Fixed bug in getVisualInfoFromString(): visuals not reloaded on + display mode change. Reload visuals each time they are queried. + This fixes a problem with Win32 because the list of availabe Visuals + (Pixelformats) changes after a change in displaymode. The problem + occurs when switching to gamemode and back. Thanks to Michael + Wimmer for pointing this out & providing the fix. + + (Oct 3, '01) + x Fixed bug in XGetVisualInfo(): pixelformats enumerated incorrectly. + Passing 0 as a pixelformat index to DescribePixelFormat gives + unpredictible results (e.g., this fails on the Voodoo opengl32.dll + and always reports 0 as the last available pixelformat index). + Thanks to Michael Wimmer for pointing this out & providing the fix. + + (Oct 3, '01) + x Fixed bug in glXGetConfig(): pixelformats enumerated incorrectly. The + test was OpenGL support OR draw to window, but should be AND. Thanks + to Michael Wimmer for pointing this out & providing the fix. + + (Sep 28, '01) + x Fixed glutChangeToSubMenu()/glutChangeToMenuEntry() bug where if you + went back and forth between a submenu and a plain entry, the submenu + wouldn't be updated properly. + + (Sep 28, '01) + x glutSetIconTitle() is now a nop. + + (Sep 28, '01) + x glutFullScreen() now sets the window as TOPMOST, therefore, the + window will always be on top (this essentially disables alt-tabbing). + + (Sep 28, '01) + x The key repeat ignore flag is now honored correctly. + + (Sep 28, '01) + x Key presses are now reported more accurately and fully, in + particular, modified up events (i.e., SHIFT-2) are now reported + correctly. + + (Sep 28, '01) + x Subwindows nested arbitrarily deep get their keyboard callbacks + correctly now. + + (Sep 28, '01) + x Major rewrite of the window procedure code to clean it up and make + way for other bug fixes. + + (Sep 23, '01) + x Fixed noof example program to use RAND_MAX instead of assumed + max of 2147483647.0. (Now it looks _much_ better!) + + (Sep 22, '01) + x Fixed sunlight example program. globe.raw data file was corrupt, + added a new one. + + (Sep 22, '01) + x Fixed zcomposite example program to print message if overlay + support is not found (instead of crashing). + + (Jan 22, '01) + x Fixed malloc(0) bug in Win32 version of XGetVisualInfo. Thanks + to Kekoa Proudfoot for bringing this to my attention. + + (Dec 12, '00) + x Added data files for the advanced & advanced97 programs. + + (Dec 12, '00) + x Added Developer Studio 6 project and workspace files for pretty + much everything (the stuff left out was usually unix specific). + + (Dec 7, '00) + x Fixed several compilation problems & corrupt files. Thanks to + Alexander Stohr for bringing these to my attention and providing + detailed fixes. + + (Dec 6, '00) + x Fixed compiler support for lcc. Thanks to Gordon for bringing + this to my attention and debugging fixes. + + (Nov 8, '00) + x Fixed submenu problem (sometimes the menu callback was not + called for valid items). Thanks to Michael Keeley. + + (Oct 16, '00) + x Corrected corrupt duck.iv file. Thanks to Jon Willeke for finding + this problem. + + (Sept 27, '00) + x Fixed bug in processWorkList that could cause a hang. Thanks to + Bill Volz & Daniel Azuma. + + (Sept 26, '00) + x Added mui DLL project file (thanks to DMWeldy@ugsolutions.com). + + (Sept 9, '00) + x Fixed Delete key bug (crash when no keyboard callback was + registered, but a special key callback was). Thanks to + Kent Bowling (kent_bowling@hotmail.com) for finding this bug. + + (May 18, '00) + x Fixed subwindow keyboard callbacks. + + (May 22, '97) + o Menus don't work under Windows 95 + x Fixed! Added a unique identifier to each menu item, and a + search function to grab a menu item given the unique identifier. + + (May 21, '97) + o A few minor bug fixes here and there. + x Thanks to Bruce Silberman and Chris Vale for their help with + this. We now have a DLL! + + (Apr 25, '97) + o DLL version of the library is coming (as soon as I figure out + how to do it -- if you know, let me know). + x Thanks to Bruce Silberman and Chris Vale for their help with + this. We now have a DLL! + + (Apr 24, '97) + x Added returns to KEY_DOWN etc messages so that the F10 key + doesn't toggle the system menu anymore. + + (Apr 7, '97) + o Palette is incorrect for modes other than TrueColor. + x Fixed this by forcing a default palette in modes that aren't + Truecolor in order to 'simulate' it. The applications + program shouldn't have to do this IMHO, but I guess we + can't argue with Microsoft (well, we can, but what good + will it do?). + + (Apr 2, '97) + x Added glut.ide file for Borland users. + + (Apr 2, '97) + x Fixed a bug in the WM_QUERYNEWPALETTE message. Wasn't + checking for a null colormap, then de-ref'd it. Oops. + + (Mar 13, '97) + o glutTimerFunc: + Currently, GLUT for Win32 programs busy waits when there is + an outstanding timer event (i.e., there is no select() + call). I haven't found this to be a problem, but I plan to + fix it just because I can't bear the thought of a busy wait. + x Added a timer event and a wait in the main loop. This fixes + the CPU spike. + + (Mar 11, '97) + x Fixed subwindow visibility. The visibility callback of + subwindows wasn't being called, now it is. + + (Mar 11, '97) + o glutGetHDC, glutGetHWND: + In order to support additional dialog boxes, wgl fonts, and + a host of other Win32 dependent structures, two functions + have been added that operate on the current window in GLUT. + The first (glutGetHDC) returns a handle to the current + windows device context. The second (glutGetHWND) returns + handle to the current window. + x Took these out to preserve GLUT portability. + + (Mar 11, '97) + x Fixed the glutWarpPointer() coordinates. Were relative to + the screen, now relative to window (client area) origin + (which is what they're supposed to be). + + (Mar 11, '97) + o glutCreateMenu, glutIdleFunc: + Menu's are modal in Win32. That is, they don't allow any + messages to be processed while they are up. Therefore, if + an idle function exists, it will not be called while + processing a menu. + x Fixed! I've put in a timer function that fires every + millisecond while a menu is up. The timer function handles + idle and timer events only (which should be the only + functions that are firing when a menu is up anyway). + + (Mar 7 '97) + x Fixed minor bugs tracked down by the example programs. + + (Mar 6, '97) + x Merged 3.3 GLUT for X11 into 3.2 GLUT for Win32. New code + structure allows for EASY merging! + + o In Win32, the parent gets the right to set the cursor of + any of its children. Therefore, a child windows cursor + will 'blink' between its cursor and its parent. + x Fixed this by checking whether the cursor is in a child + window or not. + + (Feb 28 '97) + o On initial bringup apps are getting 2 display callbacks. + x Fixed by the Fev 28 re-write. + + o Some multiple window (not subwindow) functionality is messed up. + See the sphere.exe program. + x Fixed by the Feb 28 re-write. + + o GLUT for Win32 supports color index mode ONLY in a paletted + display mode (i.e., 256 or 16 color mode). + x Fixed this in the re-write. If you can get a color index + visual (pixel format) you can use color index mode. + + (Feb 28 '97) + o Quite a few bugs (and incompatibilities) were being caused + by the structure that I used in the previous port of GLUT. + Therefore I decided that it would be best to "get back to + the roots". I re-implemented most of glut trying to stick + with the structure layed out by Mark. The result is a much + more stable version that passes ALL (!) (except overlay) + the tests provided by Mark. In addition, this new + structure will allow future enhancements by Mark to be + integrated much more quickly into the Win32 version. Also, + I'm now ordering the bugs in reverse, so that the most + recently fixed appear at the top of the list. + + (9/8/96) + o Changed the glutGetModifiers code to produce an error if not + called in the core input callbacks. + + (9/11/96) + o If the alt key is pressed with more than one other modifier key + it acts as if it is stuck -- it stays selected until pressed + and released again. + x Fixed. + + (9/12/96) + o When a submenu is attached to a menu, sometimes a GPF occurs. + Fixed. Needed to set the submenu before referencing it's members. + + o Kenny: Also, one little problem, I attached the menu to the + right-button, but when the left-button is pressed I detach + it to give the right-button new meaning; if I pop-up the menu and I + don't want to select anything, like most users, I click off of the + menu to make it disappear. When I do this, I get a GLUT error and + the program terminates because I am altering the menu attachment + from within the button press while the menu is active. + x Fixed. Needed to finish the menu when the user presses the button, + not just when a button is released. + + o GLUT for Win32 emulates a middle mouse button by checking if + both mouse buttons are down. This causes a lot of problems with + the menu and other multiple mouse button things. + x Fixed. No more middle mouse button emulation. Perhaps it would + be a good idea to emulate the middle mouse button (if not present) + with a key? + + (9/15/96) + o Added code to accept a user defined icon. If no icon is provided, + a default icon is loaded. + + (9/19/96) + o Shane: Command line options seem to be screwed up. (9/13) + x Fixed. The geometry command line was broken, and so was the + gldebug command line. + + o Fixed a bug in the default glut reshape. It was looking for the + parent of the current window and GPF'ing if there wasn't a parent. + Put in a check for a parent, and if none is there, use the + child. + + o Idle function sucks up all processor cycles. (9/8/96) + x I don't know if this is avoidable. If you have a tight rendering + loop, it may be that the processor time is going to be sucked up + no matter what. You can add a sleep() to the end of your render + loop if you would like to yeild to other processes and you don't + care too much about the speed of your rendering loop. If you have + Hardware that supports OpenGL (like a 3Dpro card, or GLint card) + then this should be less of a problem, since it won't be rendering + in software. (9/11/96) + + o If a window is fully obscured by another window, the visibility + callback is NOT called. As far as I can tell, this is a limitation + of the Win32 api, but a workaround is being searched for. (9/8/96) + x Limitation of the Win32 API + + o Fixed the entry functions. They only work if the keyboard focus + changes. Therefore, in most Win32 systems, the mouse must be + pressed outside of the window to get a GLUT_LEFT message and + then pressed inside the window for a GLUT_ENTERED message. + + o Alt modifier key doesn't work with keyboard callback. (9/8/96) + x Probably okay, because the glut spec says that these keys can + be intercepted by the system (which the alt key is...) (9/11/96) + + (11/17/96) + o glutRemoveMenuItem() not working properly. + x Thanks to Gary (grc@maple.civeng.rutgers.edu) for the fix to + this one. + + o Timer functions are messed up. + x Thanks to Joseph Galbraith for the fix to this one. + + (12/9/96) + o One (minor) difference came up between the X version of glut + and the nt one which you should know about. It is not a new + problem, and it concerns co-ords returned to the pointer + callbacks. (glutMotionFunc, glutMouseFunc) + Under X, you get co-ords in the range 0 +/- 2^15, under NT + you get 0..2^16. This is only really a problem when moving + above or to the left of the window. + eg dragging one pixel ABOVE the window will give :- + under x11 : y = -1 + under nt : y = 2^16 -1 + x Put in fix provided by Shane Clauson. + + (12/17/96) + o Idle functions not working properly for multiple windows. + x Fixed this by posting an idle message to every window in the + window list when idle. + + (12/18/96) + o glutSetCursor() was misbehaving (lthomas@cco.caltech.edu). + x Win32 requires that the hCursor member of the window class + be set to NULL when the class is registered or whenever the + mouse is moved, the original cursor is replaced (go + figure!). Now sets the cursor whenever a WM_MOUSEMOVE message + is received, because the WM_SETCURSOR event resets the cursor + even when in the decoration area. + + o Geometry is not being handled quite right. The numbers don't + take into account the window decorations. That is, if I say + make a window 100x100, then the WHOLE window (not just the + client area) is 100x100. Therefore, the client (opengl) area + is smaller than 100x100. (9/8/96) + x Fixed. Added code to subtract the decoration size on glutGet() + and add the decoration size on glutReshapeWindow(). + + o Multiple glutPostRedisplay() calls are NOT being combined. + To get round the "coalesce" problem on glutPostRedisplay, + the easiest solution is to roll-your-own coalesce by + keeping a global "dirty" flag in the app (eg replace all + calls to glutPostRedisplay with image_dirty=TRUE;), and to + handle image_dirty with a single glutPostRedisplay in the + idle callback when required. (erk - but increases + performance for my particular app (a rendering engine on + the end of a pipleine with a stream of graphics updates) by + a couple of orders of magnitude ! ) (9/8/96) + x Added code to coalesce redisplays. Every idle cycle, a + check is made to see which windows need redisplay, if they + need it, a redisplay is posted. The glutPostRedisplay() + call is just a stub that sets a flag. + + +THANKS: + + Special thanks to the following people for extensive testing, + suggestions, fixes and help: + + Alexander Stohr + Shane Clauson + Kenny Hoff + Richard Readings + Paul McQuesten + Philip Winston + JaeWoo Ahn + Joseph Galbraith + Paula Higgins + Sam Fortin + Chris Vale + Bill Mitchell + + and of course, the original author of GLUT: + Mark Kilgard. + + and many others... + + +COPYRIGHT: + +The OpenGL Utility Toolkit distribution for Win32 (Windows NT & +Windows 95) contains source code modified from the original source +code for GLUT version 3.3 which was developed by Mark J. Kilgard. The +original source code for GLUT is Copyright 1997 by Mark J. Kilgard. +GLUT for Win32 is Copyright 1997 by Nate Robins and is not in the +public domain, but it is freely distributable without licensing fees. +It is provided without guarantee or warrantee expressed or implied. +It was ported with the permission of Mark J. Kilgard by Nate Robins. + +THIS SOURCE CODE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER +EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + +OpenGL (R) is a registered trademark of Silicon Graphics, Inc. diff --git a/test/models-nonbsd/3D/mar_rifle.source.txt b/test/models-nonbsd/3D/mar_rifle.source.txt index ac8721d26..c0cd5fe6d 100644 --- a/test/models-nonbsd/3D/mar_rifle.source.txt +++ b/test/models-nonbsd/3D/mar_rifle.source.txt @@ -1,18 +1,18 @@ -===================================================================== - -From http://telias.free.fr -Model copyright: Elias Tsiantas - -===================================================================== - -Downloaded 4th November 2008. -Notice found on the page: - -" -Free the models is a site that offers free 3d models in 3ds, bryce, poser, -lightwave and md2 format. Also a great collection of textures to use in -your favorite modelling and rendering program. All the content is free -for any use. In the future more 3d formats will be added and some other -sections such as wallpapers, 3d screensavers, 3d coding source code and -tutorials. -" +===================================================================== + +From http://telias.free.fr +Model copyright: Elias Tsiantas + +===================================================================== + +Downloaded 4th November 2008. +Notice found on the page: + +" +Free the models is a site that offers free 3d models in 3ds, bryce, poser, +lightwave and md2 format. Also a great collection of textures to use in +your favorite modelling and rendering program. All the content is free +for any use. In the future more 3d formats will be added and some other +sections such as wallpapers, 3d screensavers, 3d coding source code and +tutorials. +" diff --git a/test/models-nonbsd/3DS/cart_wheel.source.txt b/test/models-nonbsd/3DS/cart_wheel.source.txt index ab926db96..6f43a3a22 100644 --- a/test/models-nonbsd/3DS/cart_wheel.source.txt +++ b/test/models-nonbsd/3DS/cart_wheel.source.txt @@ -1,18 +1,18 @@ -===================================================================== - -From http://telias.free.fr -Model copyright: Elias Tsiantas - -===================================================================== - -Downloaded 4th November 2008 (Obama ftw!). -Notice found on the page: - -" -Free the models is a site that offers free 3d models in 3ds, bryce, poser, -lightwave and md2 format. Also a great collection of textures to use in -your favorite modelling and rendering program. All the content is free -for any use. In the future more 3d formats will be added and some other -sections such as wallpapers, 3d screensavers, 3d coding source code and -tutorials. -" +===================================================================== + +From http://telias.free.fr +Model copyright: Elias Tsiantas + +===================================================================== + +Downloaded 4th November 2008 (Obama ftw!). +Notice found on the page: + +" +Free the models is a site that offers free 3d models in 3ds, bryce, poser, +lightwave and md2 format. Also a great collection of textures to use in +your favorite modelling and rendering program. All the content is free +for any use. In the future more 3d formats will be added and some other +sections such as wallpapers, 3d screensavers, 3d coding source code and +tutorials. +" diff --git a/test/models-nonbsd/3DS/jeep1.3ds.readme.txt b/test/models-nonbsd/3DS/jeep1.3ds.readme.txt index 14b0bd9eb..d17d5e0e9 100644 --- a/test/models-nonbsd/3DS/jeep1.3ds.readme.txt +++ b/test/models-nonbsd/3DS/jeep1.3ds.readme.txt @@ -1,15 +1,15 @@ -Jeep designed, modelled and skinned by me, Psionic - -FREE for use however you like, credits are appreciated!!! - -It was modelled in Milkshape 3D and includes the MS3D files oriented for X or B3D format (BlitzBasic 3D), its 2032 polys with a 512x512 jpg texture map. There are two skin variations plus a UV template to help out if you want to create your own skin variations. - -I'd love to see a few screenshots of it being used in-game so feel free to stop by my site and maybe drop by my forums and show us all what your doing with it!!!!!!! - -Check out more of my work at:- - -http://xu1productions.com/3dstudio/index.html - 3D Game Resources - -http://www.psionicdesign.com - My Main 2D/3D Digital Art site - +Jeep designed, modelled and skinned by me, Psionic + +FREE for use however you like, credits are appreciated!!! + +It was modelled in Milkshape 3D and includes the MS3D files oriented for X or B3D format (BlitzBasic 3D), its 2032 polys with a 512x512 jpg texture map. There are two skin variations plus a UV template to help out if you want to create your own skin variations. + +I'd love to see a few screenshots of it being used in-game so feel free to stop by my site and maybe drop by my forums and show us all what your doing with it!!!!!!! + +Check out more of my work at:- + +http://xu1productions.com/3dstudio/index.html - 3D Game Resources + +http://www.psionicdesign.com - My Main 2D/3D Digital Art site + Psionic 2002 \ No newline at end of file diff --git a/test/models-nonbsd/3DS/mar_rifle.source.txt b/test/models-nonbsd/3DS/mar_rifle.source.txt index ab926db96..6f43a3a22 100644 --- a/test/models-nonbsd/3DS/mar_rifle.source.txt +++ b/test/models-nonbsd/3DS/mar_rifle.source.txt @@ -1,18 +1,18 @@ -===================================================================== - -From http://telias.free.fr -Model copyright: Elias Tsiantas - -===================================================================== - -Downloaded 4th November 2008 (Obama ftw!). -Notice found on the page: - -" -Free the models is a site that offers free 3d models in 3ds, bryce, poser, -lightwave and md2 format. Also a great collection of textures to use in -your favorite modelling and rendering program. All the content is free -for any use. In the future more 3d formats will be added and some other -sections such as wallpapers, 3d screensavers, 3d coding source code and -tutorials. -" +===================================================================== + +From http://telias.free.fr +Model copyright: Elias Tsiantas + +===================================================================== + +Downloaded 4th November 2008 (Obama ftw!). +Notice found on the page: + +" +Free the models is a site that offers free 3d models in 3ds, bryce, poser, +lightwave and md2 format. Also a great collection of textures to use in +your favorite modelling and rendering program. All the content is free +for any use. In the future more 3d formats will be added and some other +sections such as wallpapers, 3d screensavers, 3d coding source code and +tutorials. +" diff --git a/test/models-nonbsd/3DS/mp5_sil.source.txt b/test/models-nonbsd/3DS/mp5_sil.source.txt index ab926db96..6f43a3a22 100644 --- a/test/models-nonbsd/3DS/mp5_sil.source.txt +++ b/test/models-nonbsd/3DS/mp5_sil.source.txt @@ -1,18 +1,18 @@ -===================================================================== - -From http://telias.free.fr -Model copyright: Elias Tsiantas - -===================================================================== - -Downloaded 4th November 2008 (Obama ftw!). -Notice found on the page: - -" -Free the models is a site that offers free 3d models in 3ds, bryce, poser, -lightwave and md2 format. Also a great collection of textures to use in -your favorite modelling and rendering program. All the content is free -for any use. In the future more 3d formats will be added and some other -sections such as wallpapers, 3d screensavers, 3d coding source code and -tutorials. -" +===================================================================== + +From http://telias.free.fr +Model copyright: Elias Tsiantas + +===================================================================== + +Downloaded 4th November 2008 (Obama ftw!). +Notice found on the page: + +" +Free the models is a site that offers free 3d models in 3ds, bryce, poser, +lightwave and md2 format. Also a great collection of textures to use in +your favorite modelling and rendering program. All the content is free +for any use. In the future more 3d formats will be added and some other +sections such as wallpapers, 3d screensavers, 3d coding source code and +tutorials. +" diff --git a/test/models-nonbsd/3DS/pyramob.3ds.readme.txt b/test/models-nonbsd/3DS/pyramob.3ds.readme.txt index 7f6cf0361..bf1858410 100644 --- a/test/models-nonbsd/3DS/pyramob.3ds.readme.txt +++ b/test/models-nonbsd/3DS/pyramob.3ds.readme.txt @@ -1,12 +1,12 @@ -hello! - -fell free to use the object...so do what U want! -& sent me your pictures...:-) -for commercial use, contact me! - -http://www.elektrobar.com/lux/ - -or mail to: -lux@elektrobar.com - +hello! + +fell free to use the object...so do what U want! +& sent me your pictures...:-) +for commercial use, contact me! + +http://www.elektrobar.com/lux/ + +or mail to: +lux@elektrobar.com + have fun.....VIRLUX \ No newline at end of file diff --git a/test/models-nonbsd/ASE/Rifle.source.txt b/test/models-nonbsd/ASE/Rifle.source.txt index 914c69466..04d40a85d 100644 --- a/test/models-nonbsd/ASE/Rifle.source.txt +++ b/test/models-nonbsd/ASE/Rifle.source.txt @@ -1,25 +1,25 @@ -===================================================================== - -From http://telias.free.fr -Model copyright: Elias Tsiantas - -===================================================================== - -Downloaded 4th November 2008 (Obama ftw!). -Notice found on the page: - -" -Free the models is a site that offers free 3d models in 3ds, bryce, poser, -lightwave and md2 format. Also a great collection of textures to use in -your favorite modelling and rendering program. All the content is free -for any use. In the future more 3d formats will be added and some other -sections such as wallpapers, 3d screensavers, 3d coding source code and -tutorials. -" - - - -INFO -==== - +===================================================================== + +From http://telias.free.fr +Model copyright: Elias Tsiantas + +===================================================================== + +Downloaded 4th November 2008 (Obama ftw!). +Notice found on the page: + +" +Free the models is a site that offers free 3d models in 3ds, bryce, poser, +lightwave and md2 format. Also a great collection of textures to use in +your favorite modelling and rendering program. All the content is free +for any use. In the future more 3d formats will be added and some other +sections such as wallpapers, 3d screensavers, 3d coding source code and +tutorials. +" + + + +INFO +==== + CONVERTED FROM 3DS TO ASE WITH AC3D \ No newline at end of file diff --git a/test/models-nonbsd/ASE/Rifle2.source.txt b/test/models-nonbsd/ASE/Rifle2.source.txt index f0dda0b20..2072ddf13 100644 --- a/test/models-nonbsd/ASE/Rifle2.source.txt +++ b/test/models-nonbsd/ASE/Rifle2.source.txt @@ -1,24 +1,24 @@ -===================================================================== - -From http://telias.free.fr -Model copyright: Elias Tsiantas - -===================================================================== - -Downloaded 4th November 2008 (Obama ftw!). -Notice found on the page: - -" -Free the models is a site that offers free 3d models in 3ds, bryce, poser, -lightwave and md2 format. Also a great collection of textures to use in -your favorite modelling and rendering program. All the content is free -for any use. In the future more 3d formats will be added and some other -sections such as wallpapers, 3d screensavers, 3d coding source code and -tutorials. -" - - -INFO -==== - +===================================================================== + +From http://telias.free.fr +Model copyright: Elias Tsiantas + +===================================================================== + +Downloaded 4th November 2008 (Obama ftw!). +Notice found on the page: + +" +Free the models is a site that offers free 3d models in 3ds, bryce, poser, +lightwave and md2 format. Also a great collection of textures to use in +your favorite modelling and rendering program. All the content is free +for any use. In the future more 3d formats will be added and some other +sections such as wallpapers, 3d screensavers, 3d coding source code and +tutorials. +" + + +INFO +==== + CONVERTED FROM 3DS TO ASE WITH AC3D \ No newline at end of file diff --git a/test/models-nonbsd/B3D/dwarf.source.txt b/test/models-nonbsd/B3D/dwarf.source.txt index c062dcabf..1a0040fba 100644 --- a/test/models-nonbsd/B3D/dwarf.source.txt +++ b/test/models-nonbsd/B3D/dwarf.source.txt @@ -1,51 +1,51 @@ -Dwarf lowpoly model Pack -Copyright 2004, Psionic Design -e-mail: psionic@blueyonder.co.uk -Used with permission. - - -INSTALLATION INSTRUCTIONS: - -To install, simply unzip to your hard drive with the "Use Folder Names" option turned on. And that's it you're ready to go! - - - -USAGE INFORMATION: - -Each zip contains the models, textures and animation info for that particular format! - -Please Read the "animationinfo.txt" file included in each zip for the exact frames of animation to use - -Credits to me "Psionic" are really appreciated but are not essential ;-) - -Any questions, screenshots of him in use etc drop by my site or email me at:- - -website: http://www.psionic3d.co.uk -email: psionic@blueyonder.co.uk - - - - -WHAT'S INCLUDED IN THE ZIP: - -ReadMe.txt - This file -b3d.zip - Blitz 3D Format models and textures -ms3d.zip - Milkshape 3D Format models and textures -x.zip - DarkBasic Direct X 8 Format models and textures - - - -RESTRICTIONS: - -This model pack is available for use in freeware, shareware, commercial games/software with the following restrictions:- - -**You may not sell/re-sell this model pack or claim it as your own. -***You may not redistribute this pack in some other model pack through a website or on a compilation CD of any kind, without my written consent. - - -Psi -http://www.psionic3d.co.uk - - - - +Dwarf lowpoly model Pack +Copyright 2004, Psionic Design +e-mail: psionic@blueyonder.co.uk +Used with permission. + + +INSTALLATION INSTRUCTIONS: + +To install, simply unzip to your hard drive with the "Use Folder Names" option turned on. And that's it you're ready to go! + + + +USAGE INFORMATION: + +Each zip contains the models, textures and animation info for that particular format! + +Please Read the "animationinfo.txt" file included in each zip for the exact frames of animation to use + +Credits to me "Psionic" are really appreciated but are not essential ;-) + +Any questions, screenshots of him in use etc drop by my site or email me at:- + +website: http://www.psionic3d.co.uk +email: psionic@blueyonder.co.uk + + + + +WHAT'S INCLUDED IN THE ZIP: + +ReadMe.txt - This file +b3d.zip - Blitz 3D Format models and textures +ms3d.zip - Milkshape 3D Format models and textures +x.zip - DarkBasic Direct X 8 Format models and textures + + + +RESTRICTIONS: + +This model pack is available for use in freeware, shareware, commercial games/software with the following restrictions:- + +**You may not sell/re-sell this model pack or claim it as your own. +***You may not redistribute this pack in some other model pack through a website or on a compilation CD of any kind, without my written consent. + + +Psi +http://www.psionic3d.co.uk + + + + diff --git a/test/models-nonbsd/B3D/turtle.source.txt b/test/models-nonbsd/B3D/turtle.source.txt index 187fa95a7..fab387bdc 100644 --- a/test/models-nonbsd/B3D/turtle.source.txt +++ b/test/models-nonbsd/B3D/turtle.source.txt @@ -1,11 +1,11 @@ -turtle1.b3d -Copyright 2004, Psionic Design -e-mail: psionic@blueyonder.co.uk -Used with permission. - -RESTRICTIONS: - -This model pack is available for use in freeware, shareware, commercial games/software with the following restrictions:- - -**You may not sell/re-sell this model pack or claim it as your own. +turtle1.b3d +Copyright 2004, Psionic Design +e-mail: psionic@blueyonder.co.uk +Used with permission. + +RESTRICTIONS: + +This model pack is available for use in freeware, shareware, commercial games/software with the following restrictions:- + +**You may not sell/re-sell this model pack or claim it as your own. ***You may not redistribute this pack in some other model pack through a website or on a compilation CD of any kind, without my written consent. \ No newline at end of file diff --git a/test/models-nonbsd/BLEND/bob.source.txt b/test/models-nonbsd/BLEND/bob.source.txt index ac86757d1..592693550 100644 --- a/test/models-nonbsd/BLEND/bob.source.txt +++ b/test/models-nonbsd/BLEND/bob.source.txt @@ -1,31 +1,31 @@ - ----------------------------------------------------------------------------------------------- -TITLE : Bob, MD5 character source file -AUTHOR : Ken Beyer (kat) -EMAIL ADDRESS : info@katsbits.com -HOMEPAGE URL : http://www.katsbits.com - - -MODEL NAME/s -Zip file contains *.blend source file and TGA texture assets for MD5 format testing. -Files and media are provided "as is" without any explicit or implied warranty of fuctionality. - - -DISTRIBUTION -Copyright © 2009 KatsBits. Distribution MUST include this readme and authorship attribution. -Commercial use is permitted with written licensed permission. ----------------------------------------------------------------------------------------------- - -Files: - - Bob.md5mesh - - Bob.md5anim - - Bob.blend - - ./*.png - -Changes: - - converted all tga's to png, updated .blend and .md5mesh accordingly - - removed absolute texture paths from the md5mesh file - - minor downscaling of all textures to fit in less bytes - - - + +---------------------------------------------------------------------------------------------- +TITLE : Bob, MD5 character source file +AUTHOR : Ken Beyer (kat) +EMAIL ADDRESS : info@katsbits.com +HOMEPAGE URL : http://www.katsbits.com + + +MODEL NAME/s +Zip file contains *.blend source file and TGA texture assets for MD5 format testing. +Files and media are provided "as is" without any explicit or implied warranty of fuctionality. + + +DISTRIBUTION +Copyright © 2009 KatsBits. Distribution MUST include this readme and authorship attribution. +Commercial use is permitted with written licensed permission. +---------------------------------------------------------------------------------------------- + +Files: + - Bob.md5mesh + - Bob.md5anim + - Bob.blend + - ./*.png + +Changes: + - converted all tga's to png, updated .blend and .md5mesh accordingly + - removed absolute texture paths from the md5mesh file + - minor downscaling of all textures to fit in less bytes + + + diff --git a/test/models-nonbsd/DXF/rifle.source.txt b/test/models-nonbsd/DXF/rifle.source.txt index f37e2cf8d..3e88f009f 100644 --- a/test/models-nonbsd/DXF/rifle.source.txt +++ b/test/models-nonbsd/DXF/rifle.source.txt @@ -1,23 +1,23 @@ -===================================================================== - -From http://telias.free.fr -Model copyright: Elias Tsiantas - -===================================================================== - -Downloaded 4th November 2008 (Obama ftw!). -Notice found on the page: - -" -Free the models is a site that offers free 3d models in 3ds, bryce, poser, -lightwave and md2 format. Also a great collection of textures to use in -your favorite modelling and rendering program. All the content is free -for any use. In the future more 3d formats will be added and some other -sections such as wallpapers, 3d screensavers, 3d coding source code and -tutorials. -" - -INFO -==== - +===================================================================== + +From http://telias.free.fr +Model copyright: Elias Tsiantas + +===================================================================== + +Downloaded 4th November 2008 (Obama ftw!). +Notice found on the page: + +" +Free the models is a site that offers free 3d models in 3ds, bryce, poser, +lightwave and md2 format. Also a great collection of textures to use in +your favorite modelling and rendering program. All the content is free +for any use. In the future more 3d formats will be added and some other +sections such as wallpapers, 3d screensavers, 3d coding source code and +tutorials. +" + +INFO +==== + COnverted from 3ds to DXF with Ac3D \ No newline at end of file diff --git a/test/models-nonbsd/IFC/linklist.txt b/test/models-nonbsd/IFC/linklist.txt index 041435c50..06ad3844b 100644 --- a/test/models-nonbsd/IFC/linklist.txt +++ b/test/models-nonbsd/IFC/linklist.txt @@ -1,4 +1,4 @@ -Good IFC test cases -=================== - +Good IFC test cases +=================== + http://www.iai.fzk.de/www-extern/index.php?id=1135 \ No newline at end of file diff --git a/test/models-nonbsd/IRR/skybox/credits.txt b/test/models-nonbsd/IRR/skybox/credits.txt index 0b2135e88..b2b601392 100644 --- a/test/models-nonbsd/IRR/skybox/credits.txt +++ b/test/models-nonbsd/IRR/skybox/credits.txt @@ -1,11 +1,11 @@ -This skybox is basing on a skydome texture from - -http://mikepan.homeip.net/earth - -Downloaded November 22th, 08 -Distribution note: -"These royalty-free skydome textures work best when applied to a sphere or hemisphere" - - - -Thanks for your great work! +This skybox is basing on a skydome texture from + +http://mikepan.homeip.net/earth + +Downloaded November 22th, 08 +Distribution note: +"These royalty-free skydome textures work best when applied to a sphere or hemisphere" + + + +Thanks for your great work! diff --git a/test/models-nonbsd/LWO/LWO2/LWSReferences/QuickDraw.source.txt b/test/models-nonbsd/LWO/LWO2/LWSReferences/QuickDraw.source.txt index 80dc1df4e..bb07f8e24 100644 --- a/test/models-nonbsd/LWO/LWO2/LWSReferences/QuickDraw.source.txt +++ b/test/models-nonbsd/LWO/LWO2/LWSReferences/QuickDraw.source.txt @@ -1,31 +1,31 @@ -===================================================================== - -From http://telias.free.fr -Model copyright: Elias Tsiantas - -"These 3d models are contributed by John Hoffman and are based on -characters from a cartoon show called "Jayce and the wheel warriors" -(except the marauder) John's site: http://www3.sympatico.ca/john.hoffman" - -===================================================================== - -Downloaded 4th November 2008 (Obama ftw!). -Notice found on the page: - -" -Free the models is a site that offers free 3d models in 3ds, bryce, poser, -lightwave and md2 format. Also a great collection of textures to use in -your favorite modelling and rendering program. All the content is free -for any use. In the future more 3d formats will be added and some other -sections such as wallpapers, 3d screensavers, 3d coding source code and -tutorials. -" - - - -INFO -==== - - -These files belong to the QuickDraw model in the LWS folder - they are referenced +===================================================================== + +From http://telias.free.fr +Model copyright: Elias Tsiantas + +"These 3d models are contributed by John Hoffman and are based on +characters from a cartoon show called "Jayce and the wheel warriors" +(except the marauder) John's site: http://www3.sympatico.ca/john.hoffman" + +===================================================================== + +Downloaded 4th November 2008 (Obama ftw!). +Notice found on the page: + +" +Free the models is a site that offers free 3d models in 3ds, bryce, poser, +lightwave and md2 format. Also a great collection of textures to use in +your favorite modelling and rendering program. All the content is free +for any use. In the future more 3d formats will be added and some other +sections such as wallpapers, 3d screensavers, 3d coding source code and +tutorials. +" + + + +INFO +==== + + +These files belong to the QuickDraw model in the LWS folder - they are referenced and loaded into the LWS scene. \ No newline at end of file diff --git a/test/models-nonbsd/LWO/LWO2/rifle.source.txt b/test/models-nonbsd/LWO/LWO2/rifle.source.txt index 02680a50a..34576f0ca 100644 --- a/test/models-nonbsd/LWO/LWO2/rifle.source.txt +++ b/test/models-nonbsd/LWO/LWO2/rifle.source.txt @@ -1,24 +1,24 @@ -===================================================================== - -From http://telias.free.fr -Model copyright: Elias Tsiantas - -===================================================================== - -Downloaded 4th November 2008 (Obama ftw!). -Notice found on the page: - -" -Free the models is a site that offers free 3d models in 3ds, bryce, poser, -lightwave and md2 format. Also a great collection of textures to use in -your favorite modelling and rendering program. All the content is free -for any use. In the future more 3d formats will be added and some other -sections such as wallpapers, 3d screensavers, 3d coding source code and -tutorials. -" - - -INFO -==== - +===================================================================== + +From http://telias.free.fr +Model copyright: Elias Tsiantas + +===================================================================== + +Downloaded 4th November 2008 (Obama ftw!). +Notice found on the page: + +" +Free the models is a site that offers free 3d models in 3ds, bryce, poser, +lightwave and md2 format. Also a great collection of textures to use in +your favorite modelling and rendering program. All the content is free +for any use. In the future more 3d formats will be added and some other +sections such as wallpapers, 3d screensavers, 3d coding source code and +tutorials. +" + + +INFO +==== + CONVERTED FROM 3DS TO LWO2 WITH AC3D \ No newline at end of file diff --git a/test/models-nonbsd/LWS/QuickDraw v2.2.source.txt b/test/models-nonbsd/LWS/QuickDraw v2.2.source.txt index a40f330e5..e0c7d0f7c 100644 --- a/test/models-nonbsd/LWS/QuickDraw v2.2.source.txt +++ b/test/models-nonbsd/LWS/QuickDraw v2.2.source.txt @@ -1,15 +1,15 @@ -From http://telias.free.fr - - -Downloaded 4th November 2008 (Obama ftw!). -Notice found on the page: - -" -Free the models is a site that offers free 3d models in 3ds, bryce, poser, lightwave and md2 format. Also a great collection of textures to use in your favorite modelling and rendering program. -All the content is free for any use. -In the future more 3d formats will be added and some other sections such as wallpapers, 3d screensavers, 3d coding source code and tutorials. -" - - -CHANGES: +From http://telias.free.fr + + +Downloaded 4th November 2008 (Obama ftw!). +Notice found on the page: + +" +Free the models is a site that offers free 3d models in 3ds, bryce, poser, lightwave and md2 format. Also a great collection of textures to use in your favorite modelling and rendering program. +All the content is free for any use. +In the future more 3d formats will be added and some other sections such as wallpapers, 3d screensavers, 3d coding source code and tutorials. +" + + +CHANGES: Paths have been modified \ No newline at end of file diff --git a/test/models-nonbsd/MD2/source.txt b/test/models-nonbsd/MD2/source.txt index ab926db96..6f43a3a22 100644 --- a/test/models-nonbsd/MD2/source.txt +++ b/test/models-nonbsd/MD2/source.txt @@ -1,18 +1,18 @@ -===================================================================== - -From http://telias.free.fr -Model copyright: Elias Tsiantas - -===================================================================== - -Downloaded 4th November 2008 (Obama ftw!). -Notice found on the page: - -" -Free the models is a site that offers free 3d models in 3ds, bryce, poser, -lightwave and md2 format. Also a great collection of textures to use in -your favorite modelling and rendering program. All the content is free -for any use. In the future more 3d formats will be added and some other -sections such as wallpapers, 3d screensavers, 3d coding source code and -tutorials. -" +===================================================================== + +From http://telias.free.fr +Model copyright: Elias Tsiantas + +===================================================================== + +Downloaded 4th November 2008 (Obama ftw!). +Notice found on the page: + +" +Free the models is a site that offers free 3d models in 3ds, bryce, poser, +lightwave and md2 format. Also a great collection of textures to use in +your favorite modelling and rendering program. All the content is free +for any use. In the future more 3d formats will be added and some other +sections such as wallpapers, 3d screensavers, 3d coding source code and +tutorials. +" diff --git a/test/models-nonbsd/MD3/q3root/models/mapobjects/kt_kubalwagon/readme_kubalwagon.txt b/test/models-nonbsd/MD3/q3root/models/mapobjects/kt_kubalwagon/readme_kubalwagon.txt index 9b56b97c4..e0a978ee0 100644 --- a/test/models-nonbsd/MD3/q3root/models/mapobjects/kt_kubalwagon/readme_kubalwagon.txt +++ b/test/models-nonbsd/MD3/q3root/models/mapobjects/kt_kubalwagon/readme_kubalwagon.txt @@ -1,26 +1,26 @@ -------------------------------------------------------------------------- - -TITLE : kt_kubalwagon -AUTHOR : ken 'kat' beyer -EMAIL ADDRESS : cpdt@telinco.co.uk -HOMEPAGE URL : http://www.quake3bits.co.uk -NUMBER OF MODELS : 1 -SHADER SCRIPTS : yes - included - ------------------- -* MODEL NAME/s * -[model details below] -european_fnt_v2.md3 - -euro_rnt_2.tga (alpha'd steering wheel) -european_fnt.tga - - ------------------- - -CREDITS -ID software, eskimo roll, EMSIPE, QkenneyQ -DISTRIBUTION -as long as this readme is included...! - +------------------------------------------------------------------------- + +TITLE : kt_kubalwagon +AUTHOR : ken 'kat' beyer +EMAIL ADDRESS : cpdt@telinco.co.uk +HOMEPAGE URL : http://www.quake3bits.co.uk +NUMBER OF MODELS : 1 +SHADER SCRIPTS : yes - included + +------------------ +* MODEL NAME/s * +[model details below] +european_fnt_v2.md3 + +euro_rnt_2.tga (alpha'd steering wheel) +european_fnt.tga + + +------------------ + +CREDITS +ID software, eskimo roll, EMSIPE, QkenneyQ +DISTRIBUTION +as long as this readme is included...! + -------------------------------------------------------------------------- \ No newline at end of file diff --git a/test/models-nonbsd/MD3/readme_water.txt b/test/models-nonbsd/MD3/readme_water.txt index d80e7eb0e..cdc318ff8 100644 --- a/test/models-nonbsd/MD3/readme_water.txt +++ b/test/models-nonbsd/MD3/readme_water.txt @@ -1,26 +1,26 @@ -------------------------------------------------------------------------- - -TITLE : kt_watercan -AUTHOR : ken 'kat' beyer -EMAIL ADDRESS : cpdt@telinco.co.uk -HOMEPAGE URL : http://www.quake3bits.co.uk -NUMBER OF MODELS : 2 -SHADER SCRIPTS : n/a - ------------------- -* MODEL NAME/s * -[model details below] -watercan.md3 -watercan_dmg.md3 (dmg='damaged') - -water_can.tga 256x128 - - ------------------- - -CREDITS -ID software, eskimo roll, EMSIPE, QkenneyQ -DISTRIBUTION -as long as this readme is included...! - +------------------------------------------------------------------------- + +TITLE : kt_watercan +AUTHOR : ken 'kat' beyer +EMAIL ADDRESS : cpdt@telinco.co.uk +HOMEPAGE URL : http://www.quake3bits.co.uk +NUMBER OF MODELS : 2 +SHADER SCRIPTS : n/a + +------------------ +* MODEL NAME/s * +[model details below] +watercan.md3 +watercan_dmg.md3 (dmg='damaged') + +water_can.tga 256x128 + + +------------------ + +CREDITS +ID software, eskimo roll, EMSIPE, QkenneyQ +DISTRIBUTION +as long as this readme is included...! + -------------------------------------------------------------------------- \ No newline at end of file diff --git a/test/models-nonbsd/MD5/BoarMan.source.txt b/test/models-nonbsd/MD5/BoarMan.source.txt index cbba6edf6..50b2dfb53 100644 --- a/test/models-nonbsd/MD5/BoarMan.source.txt +++ b/test/models-nonbsd/MD5/BoarMan.source.txt @@ -1,8 +1,8 @@ - -License: Creative Commons - - Remix - - Share alike - - Attribution Author: zphr (Christian Lenke) - - - + +License: Creative Commons + - Remix + - Share alike + - Attribution Author: zphr (Christian Lenke) + + + diff --git a/test/models-nonbsd/MD5/bob.source.txt b/test/models-nonbsd/MD5/bob.source.txt index ac86757d1..592693550 100644 --- a/test/models-nonbsd/MD5/bob.source.txt +++ b/test/models-nonbsd/MD5/bob.source.txt @@ -1,31 +1,31 @@ - ----------------------------------------------------------------------------------------------- -TITLE : Bob, MD5 character source file -AUTHOR : Ken Beyer (kat) -EMAIL ADDRESS : info@katsbits.com -HOMEPAGE URL : http://www.katsbits.com - - -MODEL NAME/s -Zip file contains *.blend source file and TGA texture assets for MD5 format testing. -Files and media are provided "as is" without any explicit or implied warranty of fuctionality. - - -DISTRIBUTION -Copyright © 2009 KatsBits. Distribution MUST include this readme and authorship attribution. -Commercial use is permitted with written licensed permission. ----------------------------------------------------------------------------------------------- - -Files: - - Bob.md5mesh - - Bob.md5anim - - Bob.blend - - ./*.png - -Changes: - - converted all tga's to png, updated .blend and .md5mesh accordingly - - removed absolute texture paths from the md5mesh file - - minor downscaling of all textures to fit in less bytes - - - + +---------------------------------------------------------------------------------------------- +TITLE : Bob, MD5 character source file +AUTHOR : Ken Beyer (kat) +EMAIL ADDRESS : info@katsbits.com +HOMEPAGE URL : http://www.katsbits.com + + +MODEL NAME/s +Zip file contains *.blend source file and TGA texture assets for MD5 format testing. +Files and media are provided "as is" without any explicit or implied warranty of fuctionality. + + +DISTRIBUTION +Copyright © 2009 KatsBits. Distribution MUST include this readme and authorship attribution. +Commercial use is permitted with written licensed permission. +---------------------------------------------------------------------------------------------- + +Files: + - Bob.md5mesh + - Bob.md5anim + - Bob.blend + - ./*.png + +Changes: + - converted all tga's to png, updated .blend and .md5mesh accordingly + - removed absolute texture paths from the md5mesh file + - minor downscaling of all textures to fit in less bytes + + + diff --git a/test/models-nonbsd/MDL/IDPO (Quake1)/gijoe-readme.txt b/test/models-nonbsd/MDL/IDPO (Quake1)/gijoe-readme.txt index 93afb7cb1..2febb0583 100644 --- a/test/models-nonbsd/MDL/IDPO (Quake1)/gijoe-readme.txt +++ b/test/models-nonbsd/MDL/IDPO (Quake1)/gijoe-readme.txt @@ -1,73 +1,73 @@ -Title : G.I.Joe Skins -Filename : joemodel.zip -Version : 1 -Date : 11/05/97 -Author : Kenneth Whelan -Email : JWHELAN@pop.prodigy.net -Credits : id software, Larry Hama, Steven Polge, and Rene Post for making Quake ME - - - -Build time: ??? Time??? - -Type of Mod ------------ -Quake C : no -Sound : no -MDL : Yes - - -Format of QuakeC (if a Quake C Mod) ------------------------------------ -unified diff : no -context diff : no -.qc files : no -progs.dat : no - - -Description of the Modification -------------------------------- - -This is a new player.mdl for quake. It's main use is for bots. The Skins are Snake Eyes v4, Duke v3, Low-Light, -Storm Shadow v2, Shockwave, Repeater, Gung-Ho, Shipwreck, Dusty v3, and -Tunnel Rat v2. - - - -Known bugs -None that I know of. - -How to Install the Modification -------------------------------- - -First back up the current player.mdl(copy player.mdl player.bak). Just put -it in the progs dir in the hack your using, if any. - -Technical Details ------------------ - -can't think of any - - -Author Information ------------------- - -This is my first publicly distributed quake graphic change. -I did it to get away from the stress of school. - - -Copyright and Distribution Permissions --------------------------------------- - -You may distribute this Quake modification in any electronic format as long as - all the files in this archive remain intact and unmodified and are distributed - together. - - -Availability ------------- - -This modification is available from the following places: - - http://www.yojoe.com/ - +Title : G.I.Joe Skins +Filename : joemodel.zip +Version : 1 +Date : 11/05/97 +Author : Kenneth Whelan +Email : JWHELAN@pop.prodigy.net +Credits : id software, Larry Hama, Steven Polge, and Rene Post for making Quake ME + + + +Build time: ??? Time??? + +Type of Mod +----------- +Quake C : no +Sound : no +MDL : Yes + + +Format of QuakeC (if a Quake C Mod) +----------------------------------- +unified diff : no +context diff : no +.qc files : no +progs.dat : no + + +Description of the Modification +------------------------------- + +This is a new player.mdl for quake. It's main use is for bots. The Skins are Snake Eyes v4, Duke v3, Low-Light, +Storm Shadow v2, Shockwave, Repeater, Gung-Ho, Shipwreck, Dusty v3, and +Tunnel Rat v2. + + + +Known bugs +None that I know of. + +How to Install the Modification +------------------------------- + +First back up the current player.mdl(copy player.mdl player.bak). Just put +it in the progs dir in the hack your using, if any. + +Technical Details +----------------- + +can't think of any + + +Author Information +------------------ + +This is my first publicly distributed quake graphic change. +I did it to get away from the stress of school. + + +Copyright and Distribution Permissions +-------------------------------------- + +You may distribute this Quake modification in any electronic format as long as + all the files in this archive remain intact and unmodified and are distributed + together. + + +Availability +------------ + +This modification is available from the following places: + + http://www.yojoe.com/ + diff --git a/test/models-nonbsd/MDL/IDPO (Quake1)/steg.txt b/test/models-nonbsd/MDL/IDPO (Quake1)/steg.txt index fb8d5304b..c07c2f126 100644 --- a/test/models-nonbsd/MDL/IDPO (Quake1)/steg.txt +++ b/test/models-nonbsd/MDL/IDPO (Quake1)/steg.txt @@ -1,33 +1,33 @@ -Stegosaur Model -from the Free Models Project -www.oz.net/~simitar/model.html - - -June 3, 1997 - -created by Sirius (Dillon Aumiller) -E-mail: sirius25@hotmail.com - - -June 5, 1997 - -modified by The Serpent Lord (Seth Galbraith) -E-mail: sgalbrai@linknet.kitsap.lib.wa.us -WWW: www.oz.net/~simitar - - -This model can be used or modified for any purpose -as long as this text document is included with it -and all modellers listed in this document are -listed wherever credits are appropriate for that -purpose. - - -Help Wanted: - -The Free Models Project can use help with -models and in other areas, such as legal boilerplate -for models. - -WWW: www.oz.net/~simitar/model.html -E-mail: sgalbrai@linknet.kitsap.lib.wa.us +Stegosaur Model +from the Free Models Project +www.oz.net/~simitar/model.html + + +June 3, 1997 + +created by Sirius (Dillon Aumiller) +E-mail: sirius25@hotmail.com + + +June 5, 1997 + +modified by The Serpent Lord (Seth Galbraith) +E-mail: sgalbrai@linknet.kitsap.lib.wa.us +WWW: www.oz.net/~simitar + + +This model can be used or modified for any purpose +as long as this text document is included with it +and all modellers listed in this document are +listed wherever credits are appropriate for that +purpose. + + +Help Wanted: + +The Free Models Project can use help with +models and in other areas, such as legal boilerplate +for models. + +WWW: www.oz.net/~simitar/model.html +E-mail: sgalbrai@linknet.kitsap.lib.wa.us diff --git a/test/models-nonbsd/MDL/IDPO (Quake1)/tekmechbot.txt b/test/models-nonbsd/MDL/IDPO (Quake1)/tekmechbot.txt index a263d9c8b..dc0149b01 100644 --- a/test/models-nonbsd/MDL/IDPO (Quake1)/tekmechbot.txt +++ b/test/models-nonbsd/MDL/IDPO (Quake1)/tekmechbot.txt @@ -1,33 +1,33 @@ - -+)+)+)+)+)+)+)+)+)+)+)+)+)+)+)+)+)+)+)+)+)+)+)+)+)+)+) - -teckmechbot animated .mdl - -This model was created for the FMP, because I believe -that the FMP is a great concept !! - -There is some movement in the model. -The legs can be animated for walking, stomping, or running -around ! -Ok, it's my first model, so I will work on less polygony -in the future ;-) - - -Created By: Curiel7 -Contact: ebuy@optelnow.net (E-MAIL) -Date Created: 7/07/2000 -====================================================== - -This model can be used or modified for any purpose -as long as this text document is included with it -and all modelers listed in this document are -listed wherever credits are appropriate for that -purpose. - - -The Free Models Project can use your help with -game-oriented models and other areas - -WWW: http://www.planetquake.com/simitar -E-mail: sgalbrai@linknet.kitsap.lib.wa.us - + ++)+)+)+)+)+)+)+)+)+)+)+)+)+)+)+)+)+)+)+)+)+)+)+)+)+)+) + +teckmechbot animated .mdl + +This model was created for the FMP, because I believe +that the FMP is a great concept !! + +There is some movement in the model. +The legs can be animated for walking, stomping, or running +around ! +Ok, it's my first model, so I will work on less polygony +in the future ;-) + + +Created By: Curiel7 +Contact: ebuy@optelnow.net (E-MAIL) +Date Created: 7/07/2000 +====================================================== + +This model can be used or modified for any purpose +as long as this text document is included with it +and all modelers listed in this document are +listed wherever credits are appropriate for that +purpose. + + +The Free Models Project can use your help with +game-oriented models and other areas + +WWW: http://www.planetquake.com/simitar +E-mail: sgalbrai@linknet.kitsap.lib.wa.us + diff --git a/test/models-nonbsd/NFF/NFFSense8/credits.txt b/test/models-nonbsd/NFF/NFFSense8/credits.txt index 555721a7d..ff169151d 100644 --- a/test/models-nonbsd/NFF/NFFSense8/credits.txt +++ b/test/models-nonbsd/NFF/NFFSense8/credits.txt @@ -1,4 +1,4 @@ -teapot.nff, home4.nff - http://www.martinreddy.net/ukvrsig/wtk.html - -cokecan.nff -www.vrupl.evl.uic.edu/Eng591_Pages/cokecan.nff +teapot.nff, home4.nff - http://www.martinreddy.net/ukvrsig/wtk.html + +cokecan.nff -www.vrupl.evl.uic.edu/Eng591_Pages/cokecan.nff TODO: License status to be confirmed \ No newline at end of file diff --git a/test/models-nonbsd/OBJ/rifle.source.txt b/test/models-nonbsd/OBJ/rifle.source.txt index 842a9cfc0..b09dcda8c 100644 --- a/test/models-nonbsd/OBJ/rifle.source.txt +++ b/test/models-nonbsd/OBJ/rifle.source.txt @@ -1,27 +1,27 @@ -===================================================================== - -From http://telias.free.fr -Model copyright: Elias Tsiantas - -===================================================================== - -Downloaded 4th November 2008 (Obama ftw!). -Notices found on the page: - -" -Free the models is a site that offers free 3d models in 3ds, bryce, poser, -lightwave and md2 format. Also a great collection of textures to use in -your favorite modelling and rendering program. All the content is free -for any use. In the future more 3d formats will be added and some other -sections such as wallpapers, 3d screensavers, 3d coding source code and -tutorials. -" - -" -'Free the models' is a site dedicated to provide free content for 3d applications and 3d/game engines. The license of the content is that what you download from here is one step away from public domain. So, everything you download from here is free for any use EXCEPT it cannot be included in another free web or cd collection and it cannot be sold. Otherwise you can use it in your commercial game, 3d application or render work. You don't have to provide credit but It would be nice if you do. -" - -INFO -==== - +===================================================================== + +From http://telias.free.fr +Model copyright: Elias Tsiantas + +===================================================================== + +Downloaded 4th November 2008 (Obama ftw!). +Notices found on the page: + +" +Free the models is a site that offers free 3d models in 3ds, bryce, poser, +lightwave and md2 format. Also a great collection of textures to use in +your favorite modelling and rendering program. All the content is free +for any use. In the future more 3d formats will be added and some other +sections such as wallpapers, 3d screensavers, 3d coding source code and +tutorials. +" + +" +'Free the models' is a site dedicated to provide free content for 3d applications and 3d/game engines. The license of the content is that what you download from here is one step away from public domain. So, everything you download from here is free for any use EXCEPT it cannot be included in another free web or cd collection and it cannot be sold. Otherwise you can use it in your commercial game, 3d application or render work. You don't have to provide credit but It would be nice if you do. +" + +INFO +==== + Converted from 3DS to OBJ with AC3D \ No newline at end of file diff --git a/test/models-nonbsd/OBJ/segment.source.txt b/test/models-nonbsd/OBJ/segment.source.txt index 35e13588f..978d72d26 100644 --- a/test/models-nonbsd/OBJ/segment.source.txt +++ b/test/models-nonbsd/OBJ/segment.source.txt @@ -1,4 +1,4 @@ -Obj exported from Blender - -http://toychest.in.tum.de/wiki/projects:kuka_lwr +Obj exported from Blender + +http://toychest.in.tum.de/wiki/projects:kuka_lwr License: Creative-Commons-by-Attribution-3.0 \ No newline at end of file diff --git a/test/models-nonbsd/README.txt b/test/models-nonbsd/README.txt index a6842987b..8b244d2aa 100644 --- a/test/models-nonbsd/README.txt +++ b/test/models-nonbsd/README.txt @@ -1,3 +1,3 @@ -These models are not generally redistributable under the terms of Assimp's BSD license. Usually, an additional requirement on the use of the data is imposed (i.e. no commercial use, need credits, some creative commons variants, ...). - +These models are not generally redistributable under the terms of Assimp's BSD license. Usually, an additional requirement on the use of the data is imposed (i.e. no commercial use, need credits, some creative commons variants, ...). + So, if you re-package Assimp for use in a 'clean' OSS package, consider removing this directory. \ No newline at end of file diff --git a/test/models-nonbsd/X/dwarf-Read-Me.txt b/test/models-nonbsd/X/dwarf-Read-Me.txt index ad1583752..ecf775d0b 100644 --- a/test/models-nonbsd/X/dwarf-Read-Me.txt +++ b/test/models-nonbsd/X/dwarf-Read-Me.txt @@ -1,51 +1,51 @@ -Dwarf lowpoly model Pack -Copyright 2004, Psionic Design -e-mail: psionic@blueyonder.co.uk - - - -INSTALLATION INSTRUCTIONS: - -To install, simply unzip to your hard drive with the "Use Folder Names" option turned on. And that's it you're ready to go! - - - -USAGE INFORMATION: - -Each zip contains the models, textures and animation info for that particular format! - -Please Read the "animationinfo.txt" file included in each zip for the exact frames of animation to use - -Credits to me "Psionic" are really appreciated but are not essential ;-) - -Any questions, screenshots of him in use etc drop by my site or email me at:- - -website: http://www.psionic3d.co.uk -email: psionic@blueyonder.co.uk - - - - -WHAT'S INCLUDED IN THE ZIP: - -ReadMe.txt - This file -b3d.zip - Blitz 3D Format models and textures -ms3d.zip - Milkshape 3D Format models and textures -x.zip - DarkBasic Direct X 8 Format models and textures - - - -RESTRICTIONS: - -This model pack is available for use in freeware, shareware, commercial games/software with the following restrictions:- - -**You may not sell/re-sell this model pack or claim it as your own. -***You may not redistribute this pack in some other model pack through a website or on a compilation CD of any kind, without my written consent. - - -Psi -http://www.psionic3d.co.uk - - - - +Dwarf lowpoly model Pack +Copyright 2004, Psionic Design +e-mail: psionic@blueyonder.co.uk + + + +INSTALLATION INSTRUCTIONS: + +To install, simply unzip to your hard drive with the "Use Folder Names" option turned on. And that's it you're ready to go! + + + +USAGE INFORMATION: + +Each zip contains the models, textures and animation info for that particular format! + +Please Read the "animationinfo.txt" file included in each zip for the exact frames of animation to use + +Credits to me "Psionic" are really appreciated but are not essential ;-) + +Any questions, screenshots of him in use etc drop by my site or email me at:- + +website: http://www.psionic3d.co.uk +email: psionic@blueyonder.co.uk + + + + +WHAT'S INCLUDED IN THE ZIP: + +ReadMe.txt - This file +b3d.zip - Blitz 3D Format models and textures +ms3d.zip - Milkshape 3D Format models and textures +x.zip - DarkBasic Direct X 8 Format models and textures + + + +RESTRICTIONS: + +This model pack is available for use in freeware, shareware, commercial games/software with the following restrictions:- + +**You may not sell/re-sell this model pack or claim it as your own. +***You may not redistribute this pack in some other model pack through a website or on a compilation CD of any kind, without my written consent. + + +Psi +http://www.psionic3d.co.uk + + + + diff --git a/test/models/3DS/UVTransformTest/note.txt b/test/models/3DS/UVTransformTest/note.txt index fcb276d28..dc4bd0789 100644 --- a/test/models/3DS/UVTransformTest/note.txt +++ b/test/models/3DS/UVTransformTest/note.txt @@ -1,11 +1,11 @@ -All 'mirror' files are not absolutely correct. That's mainly -because it's difficult convert Max' handling of mirroring to -our's. - -In other words: TO DO, but only if someone REALLY needs it. - -------------------------------------------------------------- - -To see how it should look like - test/ReferenceImages -Note that the viewer has no 'decal' texture mapping mode, so +All 'mirror' files are not absolutely correct. That's mainly +because it's difficult convert Max' handling of mirroring to +our's. + +In other words: TO DO, but only if someone REALLY needs it. + +------------------------------------------------------------- + +To see how it should look like - test/ReferenceImages +Note that the viewer has no 'decal' texture mapping mode, so the usual clamping is used. \ No newline at end of file diff --git a/test/models/ASE/MotionCaptureROM.source.txt b/test/models/ASE/MotionCaptureROM.source.txt index 72542af41..222a3afbb 100644 --- a/test/models/ASE/MotionCaptureROM.source.txt +++ b/test/models/ASE/MotionCaptureROM.source.txt @@ -1,3 +1,3 @@ -"MotionCaptureROM.ase" - Free for any purpose. - +"MotionCaptureROM.ase" - Free for any purpose. + NOTE: The errors in the middle of the animation are caused by problems during recording, it's not an importer issue. \ No newline at end of file diff --git a/test/models/BLEND/HUMAN.source.txt b/test/models/BLEND/HUMAN.source.txt index 4cb20c906..9409b46d3 100644 --- a/test/models/BLEND/HUMAN.source.txt +++ b/test/models/BLEND/HUMAN.source.txt @@ -1,3 +1,3 @@ -HUMAN.blend (c) 2010, Tobias Rittig - +HUMAN.blend (c) 2010, Tobias Rittig + Redistribution and reuse allowed for any purpose, credits appreciated. \ No newline at end of file diff --git a/test/models/BVH/01_nn.bvh.source.txt b/test/models/BVH/01_nn.bvh.source.txt index a68993950..e538020a2 100644 --- a/test/models/BVH/01_nn.bvh.source.txt +++ b/test/models/BVH/01_nn.bvh.source.txt @@ -1,50 +1,50 @@ -http://sites.google.com/a/cgspeed.com/cgspeed/motion-capture/cmu-bvh-conversion - - -ReadmeFirst.txt -================ - - -READMEFIRST v1.00 last update July 20, 2008 by B. Hahne - -This READMEFIRST file accompanies the cgspeed.com "BVH conversion" -release of the Carnegie-Mellon University (CMU) Graphics Lab Motion -Capture Database. See "Where to find stuff" at the bottom of this -file for where to get the BVH conversion and/or the original CMU -dataset. - -The original CMU motion capture database isn't in BVH format - it's -in ASF/AMC format. This BVH conversion release was created by Bruce -Hahne, a hobbyist animator, in the interest of making the data more -available and easily usable by other animators. I presently (2008) -maintain the web site www.cgspeed.com, where this BVH conversion -release will be available or linked. - -The emphasis on this release is to produce BVH files that can rapidly -be used in MotionBuilder for motion retargetting. The files are not -yet particularly Poser-friendly or DazStudio-friendly, due to -incorrect assumptions that those programs have to make about the -underlying joint rotation setup. - - -[...] - - - -USAGE RIGHTS: - -CMU places no restrictions on the use of the original dataset, and I -(Bruce) place no additional restrictions on the use of this particular -BVH conversion. - -Here's the relevant paragraph from mocap.cs.cmu.edu: - - Use this data! This data is free for use in research and commercial - projects worldwide. If you publish results obtained using this data, - we would appreciate it if you would send the citation to your - published paper to jkh+mocap@cs.cmu.edu, and also would add this text - to your acknowledgments section: "The data used in this project was - obtained from mocap.cs.cmu.edu. The database was created with funding - from NSF EIA-0196217." - +http://sites.google.com/a/cgspeed.com/cgspeed/motion-capture/cmu-bvh-conversion + + +ReadmeFirst.txt +================ + + +READMEFIRST v1.00 last update July 20, 2008 by B. Hahne + +This READMEFIRST file accompanies the cgspeed.com "BVH conversion" +release of the Carnegie-Mellon University (CMU) Graphics Lab Motion +Capture Database. See "Where to find stuff" at the bottom of this +file for where to get the BVH conversion and/or the original CMU +dataset. + +The original CMU motion capture database isn't in BVH format - it's +in ASF/AMC format. This BVH conversion release was created by Bruce +Hahne, a hobbyist animator, in the interest of making the data more +available and easily usable by other animators. I presently (2008) +maintain the web site www.cgspeed.com, where this BVH conversion +release will be available or linked. + +The emphasis on this release is to produce BVH files that can rapidly +be used in MotionBuilder for motion retargetting. The files are not +yet particularly Poser-friendly or DazStudio-friendly, due to +incorrect assumptions that those programs have to make about the +underlying joint rotation setup. + + +[...] + + + +USAGE RIGHTS: + +CMU places no restrictions on the use of the original dataset, and I +(Bruce) place no additional restrictions on the use of this particular +BVH conversion. + +Here's the relevant paragraph from mocap.cs.cmu.edu: + + Use this data! This data is free for use in research and commercial + projects worldwide. If you publish results obtained using this data, + we would appreciate it if you would send the citation to your + published paper to jkh+mocap@cs.cmu.edu, and also would add this text + to your acknowledgments section: "The data used in this project was + obtained from mocap.cs.cmu.edu. The database was created with funding + from NSF EIA-0196217." + [...] \ No newline at end of file diff --git a/test/models/Collada/kwxport_test_vcolors.dae.source.txt b/test/models/Collada/kwxport_test_vcolors.dae.source.txt index d173f5a47..94ee48e4a 100644 --- a/test/models/Collada/kwxport_test_vcolors.dae.source.txt +++ b/test/models/Collada/kwxport_test_vcolors.dae.source.txt @@ -1,16 +1,16 @@ -From kwxport -http://www.kwxport.org/ - ->> -The kW Xport plug-in source is released under the MIT license. -Basically, it means "feel free to use it; credit the source; don't sue me -if something goes wrong." ->> - -MIT License - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +From kwxport +http://www.kwxport.org/ + +>> +The kW Xport plug-in source is released under the MIT license. +Basically, it means "feel free to use it; credit the source; don't sue me +if something goes wrong." +>> + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/test/models/IRR/warn_dwarf_scaling_is_intended.txt b/test/models/IRR/warn_dwarf_scaling_is_intended.txt index 1fcb03b9a..f651a8643 100644 --- a/test/models/IRR/warn_dwarf_scaling_is_intended.txt +++ b/test/models/IRR/warn_dwarf_scaling_is_intended.txt @@ -1,3 +1,3 @@ -for dawfInCellar_ChildOfCellar & dawfInCellar_SameHierarchy: - -the strange scalings of cellar and dwarf are intended. +for dawfInCellar_ChildOfCellar & dawfInCellar_SameHierarchy: + +the strange scalings of cellar and dwarf are intended. diff --git a/test/models/IRRMesh/credits.txt b/test/models/IRRMesh/credits.txt index 76ae3cb5d..a12163233 100644 --- a/test/models/IRRMesh/credits.txt +++ b/test/models/IRRMesh/credits.txt @@ -1,2 +1,2 @@ -cellar.irrmesh - From irrlight/irrEdit. Irrlicht/irredit license (which?) +cellar.irrmesh - From irrlight/irrEdit. Irrlicht/irredit license (which?) Textures resized to 400*400, improved JPEG compression to make them smaller \ No newline at end of file diff --git a/test/models/LWO/LWO2/MappingModes/earthCylindric.txt b/test/models/LWO/LWO2/MappingModes/earthCylindric.txt index 329b2f85a..46660a486 100644 --- a/test/models/LWO/LWO2/MappingModes/earthCylindric.txt +++ b/test/models/LWO/LWO2/MappingModes/earthCylindric.txt @@ -1,5 +1,5 @@ -Wikipedia Commons, -downloaded November 25th 08 - - +Wikipedia Commons, +downloaded November 25th 08 + + http://upload.wikimedia.org/wikipedia/commons/0/01/Lambert-cylindrical-equal-area-projection.jpg \ No newline at end of file diff --git a/test/models/LWO/LWO2/MappingModes/earthSpherical.source.txt b/test/models/LWO/LWO2/MappingModes/earthSpherical.source.txt index f47970009..218b339e1 100644 --- a/test/models/LWO/LWO2/MappingModes/earthSpherical.source.txt +++ b/test/models/LWO/LWO2/MappingModes/earthSpherical.source.txt @@ -1,9 +1,9 @@ -Source: - -Nasa, Monthly Global Images - -http://earthobservatory.nasa.gov/Features/BlueMarble/BlueMarble_monthlies.php - - -Downloaded November 24, 08. +Source: + +Nasa, Monthly Global Images + +http://earthobservatory.nasa.gov/Features/BlueMarble/BlueMarble_monthlies.php + + +Downloaded November 24, 08. Rescaled to 2048 * 1024 with GIMP \ No newline at end of file diff --git a/test/models/LWO/LWO2/concrete.source.txt b/test/models/LWO/LWO2/concrete.source.txt index de419f814..792fd1f89 100644 --- a/test/models/LWO/LWO2/concrete.source.txt +++ b/test/models/LWO/LWO2/concrete.source.txt @@ -1,2 +1,2 @@ -cgtextures.com - free, even for commercial use. See the licensing conditions and the FAQ the site for mroe details. +cgtextures.com - free, even for commercial use. See the licensing conditions and the FAQ the site for mroe details. Great source for free textures, btw! \ No newline at end of file diff --git a/test/models/LWO/LWO2/uvtest-source.txt b/test/models/LWO/LWO2/uvtest-source.txt index e534a4608..75e4878a7 100644 --- a/test/models/LWO/LWO2/uvtest-source.txt +++ b/test/models/LWO/LWO2/uvtest-source.txt @@ -1,2 +1,2 @@ -Regression file. +Regression file. by Tom Speed, see http://groups.google.com/group/bmx3d/browse_thread/thread/36db3b191f81be36 \ No newline at end of file diff --git a/test/models/MD2/faerie-source.txt b/test/models/MD2/faerie-source.txt index ea7ed82bb..ef0e4f196 100644 --- a/test/models/MD2/faerie-source.txt +++ b/test/models/MD2/faerie-source.txt @@ -1,24 +1,24 @@ - -From IRRLICHT/media - - -The Irrlicht Engine License - =========================== - - Copyright (C) 2002-2007 Nikolaus Gebhardt - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgement in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be clearly marked as such, and must not be - misrepresented as being the original software. + +From IRRLICHT/media + + +The Irrlicht Engine License + =========================== + + Copyright (C) 2002-2007 Nikolaus Gebhardt + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgement in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be clearly marked as such, and must not be + misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. \ No newline at end of file diff --git a/test/models/MD2/sidney-source.txt b/test/models/MD2/sidney-source.txt index ea7ed82bb..ef0e4f196 100644 --- a/test/models/MD2/sidney-source.txt +++ b/test/models/MD2/sidney-source.txt @@ -1,24 +1,24 @@ - -From IRRLICHT/media - - -The Irrlicht Engine License - =========================== - - Copyright (C) 2002-2007 Nikolaus Gebhardt - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgement in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be clearly marked as such, and must not be - misrepresented as being the original software. + +From IRRLICHT/media + + +The Irrlicht Engine License + =========================== + + Copyright (C) 2002-2007 Nikolaus Gebhardt + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgement in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be clearly marked as such, and must not be + misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. \ No newline at end of file diff --git a/test/models/MDL/MDL3 (3DGS A4)/minigun_readme.txt b/test/models/MDL/MDL3 (3DGS A4)/minigun_readme.txt index db69818e0..c2ca7c696 100644 --- a/test/models/MDL/MDL3 (3DGS A4)/minigun_readme.txt +++ b/test/models/MDL/MDL3 (3DGS A4)/minigun_readme.txt @@ -1,6 +1,6 @@ -My name: Grimmmy -Hi everybody!!! -This is my first published model so it isn't very good,but i'm still learning!.. -This model is free for everybody,but credit will be nice! -You may reach me at rojkov91@mail.ru +My name: Grimmmy +Hi everybody!!! +This is my first published model so it isn't very good,but i'm still learning!.. +This model is free for everybody,but credit will be nice! +You may reach me at rojkov91@mail.ru P.S: Excuse my bad english \ No newline at end of file diff --git a/test/models/MDL/MDL5 (3DGS A5)/minigun_mdl5_readme.txt b/test/models/MDL/MDL5 (3DGS A5)/minigun_mdl5_readme.txt index db69818e0..c2ca7c696 100644 --- a/test/models/MDL/MDL5 (3DGS A5)/minigun_mdl5_readme.txt +++ b/test/models/MDL/MDL5 (3DGS A5)/minigun_mdl5_readme.txt @@ -1,6 +1,6 @@ -My name: Grimmmy -Hi everybody!!! -This is my first published model so it isn't very good,but i'm still learning!.. -This model is free for everybody,but credit will be nice! -You may reach me at rojkov91@mail.ru +My name: Grimmmy +Hi everybody!!! +This is my first published model so it isn't very good,but i'm still learning!.. +This model is free for everybody,but credit will be nice! +You may reach me at rojkov91@mail.ru P.S: Excuse my bad english \ No newline at end of file diff --git a/test/models/MS3D/jeep1.readme.txt b/test/models/MS3D/jeep1.readme.txt index 14b0bd9eb..d17d5e0e9 100644 --- a/test/models/MS3D/jeep1.readme.txt +++ b/test/models/MS3D/jeep1.readme.txt @@ -1,15 +1,15 @@ -Jeep designed, modelled and skinned by me, Psionic - -FREE for use however you like, credits are appreciated!!! - -It was modelled in Milkshape 3D and includes the MS3D files oriented for X or B3D format (BlitzBasic 3D), its 2032 polys with a 512x512 jpg texture map. There are two skin variations plus a UV template to help out if you want to create your own skin variations. - -I'd love to see a few screenshots of it being used in-game so feel free to stop by my site and maybe drop by my forums and show us all what your doing with it!!!!!!! - -Check out more of my work at:- - -http://xu1productions.com/3dstudio/index.html - 3D Game Resources - -http://www.psionicdesign.com - My Main 2D/3D Digital Art site - +Jeep designed, modelled and skinned by me, Psionic + +FREE for use however you like, credits are appreciated!!! + +It was modelled in Milkshape 3D and includes the MS3D files oriented for X or B3D format (BlitzBasic 3D), its 2032 polys with a 512x512 jpg texture map. There are two skin variations plus a UV template to help out if you want to create your own skin variations. + +I'd love to see a few screenshots of it being used in-game so feel free to stop by my site and maybe drop by my forums and show us all what your doing with it!!!!!!! + +Check out more of my work at:- + +http://xu1productions.com/3dstudio/index.html - 3D Game Resources + +http://www.psionicdesign.com - My Main 2D/3D Digital Art site + Psionic 2002 \ No newline at end of file diff --git a/test/models/Q3D/E-AT-AT.source.txt b/test/models/Q3D/E-AT-AT.source.txt index b583e19c0..56a96f7d5 100644 --- a/test/models/Q3D/E-AT-AT.source.txt +++ b/test/models/Q3D/E-AT-AT.source.txt @@ -1,8 +1,8 @@ -Source: the3darchive.com - -Downloaded 4th November 08 (Obama ftw!) - -Copyright notice found on the page: - -Where do the models in the archive come from? +Source: the3darchive.com + +Downloaded 4th November 08 (Obama ftw!) + +Copyright notice found on the page: + +Where do the models in the archive come from? All 3D files available from the3darchive.com are from the public domain. \ No newline at end of file diff --git a/test/models/Q3D/earth.source.txt b/test/models/Q3D/earth.source.txt index b583e19c0..56a96f7d5 100644 --- a/test/models/Q3D/earth.source.txt +++ b/test/models/Q3D/earth.source.txt @@ -1,8 +1,8 @@ -Source: the3darchive.com - -Downloaded 4th November 08 (Obama ftw!) - -Copyright notice found on the page: - -Where do the models in the archive come from? +Source: the3darchive.com + +Downloaded 4th November 08 (Obama ftw!) + +Copyright notice found on the page: + +Where do the models in the archive come from? All 3D files available from the3darchive.com are from the public domain. \ No newline at end of file diff --git a/test/models/WRL/credits.txt b/test/models/WRL/credits.txt index 8024aeb81..055f73734 100644 --- a/test/models/WRL/credits.txt +++ b/test/models/WRL/credits.txt @@ -1,2 +1,2 @@ -"MotionCaptureROM.ase" Recorded using ViconIQ. -Converted to VRML with 3DS Max 2008. +"MotionCaptureROM.ase" Recorded using ViconIQ. +Converted to VRML with 3DS Max 2008. diff --git a/test/models/X/anim_test.txt b/test/models/X/anim_test.txt index ca759fd12..637ea0581 100644 --- a/test/models/X/anim_test.txt +++ b/test/models/X/anim_test.txt @@ -1,9 +1,9 @@ -Zylinder animation: - -Frame 1 - 10: Zylinder knickt ein, so dass der Knick in Richtung z+ zeigt. -Frame 10 - 18: Zylinder-Spitze streckt sich in Richtung z-. -Frame 18 - 24: Zylinder-Spitze bewegt sich zu Position in Richtung x+ - -Remarks: The exporter failed here for some reasons... although the mesh referres to four bones, only two of them are stored in the corresponding node hierarchy. So you have a mesh with 4 bones, a hirarchy with 2 nodes and a animation that affects only those two nodes. - +Zylinder animation: + +Frame 1 - 10: Zylinder knickt ein, so dass der Knick in Richtung z+ zeigt. +Frame 10 - 18: Zylinder-Spitze streckt sich in Richtung z-. +Frame 18 - 24: Zylinder-Spitze bewegt sich zu Position in Richtung x+ + +Remarks: The exporter failed here for some reasons... although the mesh referres to four bones, only two of them are stored in the corresponding node hierarchy. So you have a mesh with 4 bones, a hirarchy with 2 nodes and a animation that affects only those two nodes. + There is no timing given for the animation. You have to scale the animation manually. For this file, the timing seems to be 24 ticks per second. \ No newline at end of file diff --git a/test/models/X/kwxport_test_cubewithvcolors.source.txt b/test/models/X/kwxport_test_cubewithvcolors.source.txt index d173f5a47..94ee48e4a 100644 --- a/test/models/X/kwxport_test_cubewithvcolors.source.txt +++ b/test/models/X/kwxport_test_cubewithvcolors.source.txt @@ -1,16 +1,16 @@ -From kwxport -http://www.kwxport.org/ - ->> -The kW Xport plug-in source is released under the MIT license. -Basically, it means "feel free to use it; credit the source; don't sue me -if something goes wrong." ->> - -MIT License - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +From kwxport +http://www.kwxport.org/ + +>> +The kW Xport plug-in source is released under the MIT license. +Basically, it means "feel free to use it; credit the source; don't sue me +if something goes wrong." +>> + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/test/models/X/test.txt b/test/models/X/test.txt index 1f7698422..7a5e8e74b 100644 --- a/test/models/X/test.txt +++ b/test/models/X/test.txt @@ -1,3 +1,3 @@ -Simple textured test cube exported from Maya. Has a texture that does label each cube side uniquely, but the sides do not match DirectX coordinate space. - +Simple textured test cube exported from Maya. Has a texture that does label each cube side uniquely, but the sides do not match DirectX coordinate space. + Is not readable using D3DXLoadFrameHierarchy, needs custom text parsing. \ No newline at end of file diff --git a/test/models/invalid/readme.txt b/test/models/invalid/readme.txt index 50b5fc1ce..cab740a84 100644 --- a/test/models/invalid/readme.txt +++ b/test/models/invalid/readme.txt @@ -1,31 +1,31 @@ - -********************************************************* -GENERAL -********************************************************* - - -The files in this directory are invalid ... some of them are empty, -others have invalid vertices or faces, others are prepared to make - assimp allocate a few hundreds gigs of memory ... most are -actually regression tests, i.e. there was once a bugfix that -fixed the respective loaders. - -This test case is successful if the library (and the viewer) don't -crash. - - -********************************************************* -FILES -********************************************************* - -OutOfMemory.off - the number of faces is invalid. There won't be - enough memory so std::vector::reserve() will most likely fail. - The exception should be caught in Importer.cpp. - -empty. - These files are completely empty. The corresponding - loaders should not crash. - -malformed.obj - out-of-range vertex indices -malformed2.obj - non-existent material referenced - - + +********************************************************* +GENERAL +********************************************************* + + +The files in this directory are invalid ... some of them are empty, +others have invalid vertices or faces, others are prepared to make + assimp allocate a few hundreds gigs of memory ... most are +actually regression tests, i.e. there was once a bugfix that +fixed the respective loaders. + +This test case is successful if the library (and the viewer) don't +crash. + + +********************************************************* +FILES +********************************************************* + +OutOfMemory.off - the number of faces is invalid. There won't be + enough memory so std::vector::reserve() will most likely fail. + The exception should be caught in Importer.cpp. + +empty. - These files are completely empty. The corresponding + loaders should not crash. + +malformed.obj - out-of-range vertex indices +malformed2.obj - non-existent material referenced + + diff --git a/workspaces/xcode3/info.txt b/workspaces/xcode3/info.txt index 4a623d1ed..d22a76b6f 100644 --- a/workspaces/xcode3/info.txt +++ b/workspaces/xcode3/info.txt @@ -1,6 +1,6 @@ -The xcode project files in this directory are contributed by Andy Maloney and are not continuously updated. -Currently, it's for Assimp r352. If you're using a newer revision, watch out for missing files/includes/... - -See Andy's description at -http://sourceforge.net/tracker/index.php?func=detail&aid=2659135&group_id=226462&atid=1067634 (Tracker item 2659135) -for more information. +The xcode project files in this directory are contributed by Andy Maloney and are not continuously updated. +Currently, it's for Assimp r352. If you're using a newer revision, watch out for missing files/includes/... + +See Andy's description at +http://sourceforge.net/tracker/index.php?func=detail&aid=2659135&group_id=226462&atid=1067634 (Tracker item 2659135) +for more information. From 295a9abbdcfb86e77cf6afcd1e7f268a7f25670c Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Mon, 10 Aug 2015 13:13:01 +0200 Subject: [PATCH 35/51] Update CMakeLists.txt Fix for https://github.com/assimp/assimp/issues/166 --- code/CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index c3302ee98..351ce8da2 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -656,6 +656,11 @@ if ( MSVC ) ADD_DEFINITIONS( -D_CRT_SECURE_NO_WARNINGS ) endif ( MSVC ) +if (APPLE) + SET_TARGET_PROPERTIES( assimp PROPERTIES + INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}" + ) +endif() if (UNZIP_FOUND) SET (unzip_compile_SRCS "") else (UNZIP_FOUND) From b39446b7bbd357f9d78c6e759d3af1b16cba540f Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Mon, 10 Aug 2015 15:48:26 +0300 Subject: [PATCH 36/51] Avoid reading past EOF when encountering a malformed STL file Since IsSpaceOrNewLine returns true on '\0' we might try to read past end of buffer on line 310. Add explicit check to avoid this. --- code/STLLoader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/STLLoader.cpp b/code/STLLoader.cpp index ad445efdb..de70dd7a3 100644 --- a/code/STLLoader.cpp +++ b/code/STLLoader.cpp @@ -279,7 +279,7 @@ void STLImporter::LoadASCIIFile() break; } // facet normal -0.13 -0.13 -0.98 - if (!strncmp(sz,"facet",5) && IsSpaceOrNewLine(*(sz+5))) { + if (!strncmp(sz,"facet",5) && IsSpaceOrNewLine(*(sz+5)) && *(sz + 5) != '\0') { if (3 != curVertex) { DefaultLogger::get()->warn("STL: A new facet begins but the old is not yet complete"); From bcf3f985fb06ca1fff76e3df4c7c1ac0fdf6cb43 Mon Sep 17 00:00:00 2001 From: Andreas Henne Date: Thu, 13 Aug 2015 13:22:21 +0200 Subject: [PATCH 37/51] Fixed spelling error. --- code/PlyExporter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/PlyExporter.cpp b/code/PlyExporter.cpp index f8ff34fc2..0a23e4b75 100644 --- a/code/PlyExporter.cpp +++ b/code/PlyExporter.cpp @@ -192,7 +192,7 @@ PlyExporter::PlyExporter(const char* _filename, const aiScene* pScene, bool bina // uchar seems to be the most common type for the number of indices per polygon and int seems to be most common for the vertex indices. // For instance, MeshLab fails to load meshes in which both types are uint. Houdini seems to have problems as well. - // Obviously, using unchar will not work for meshes with polygons with more than 255 indices, but how realistic is this case? + // Obviously, using uchar will not work for meshes with polygons with more than 255 indices, but how realistic is this case? mOutput << "property list uchar int vertex_index" << endl; mOutput << "end_header" << endl; From 4cc716a0f5198f9ad9e32d79de14db535ae51c12 Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Tue, 11 Aug 2015 14:32:26 +0300 Subject: [PATCH 38/51] MDL: Fix read past end of buffer with malformed input --- code/MDLLoader.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/MDLLoader.cpp b/code/MDLLoader.cpp index 60c92661b..c5b8d63c3 100644 --- a/code/MDLLoader.cpp +++ b/code/MDLLoader.cpp @@ -355,6 +355,9 @@ void MDLImporter::InternReadFile_Quake1( ) for (unsigned int i = 0; i < (unsigned int)pcHeader->num_skins;++i) { union{BE_NCONST MDL::Skin* pcSkin;BE_NCONST MDL::GroupSkin* pcGroupSkin;}; + if (szCurrent + sizeof(MDL::Skin) > this->mBuffer + this->iFileSize) { + throw DeadlyImportError("[Quake 1 MDL] Unexpected EOF"); + } pcSkin = (BE_NCONST MDL::Skin*)szCurrent; AI_SWAP4( pcSkin->group ); From d185cea81c669cc0a2330c97a54a669892867599 Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Tue, 11 Aug 2015 15:44:51 +0300 Subject: [PATCH 39/51] AC3D: Fix read past end of buffer --- code/ACLoader.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/ACLoader.cpp b/code/ACLoader.cpp index dac85b8db..642fd5d24 100644 --- a/code/ACLoader.cpp +++ b/code/ACLoader.cpp @@ -89,6 +89,9 @@ static const aiImporterDesc desc = { // ------------------------------------------------------------------------------------------------ // read a string (may be enclosed in double quotation marks). buffer must point to " #define AI_AC_GET_STRING(out) \ + if (*buffer == '\0') { \ + throw DeadlyImportError("AC3D: Unexpected EOF in string"); \ + } \ ++buffer; \ const char* sz = buffer; \ while ('\"' != *buffer) \ From e5ddb98dde79530d3bacd83c806d36924d2accf8 Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Tue, 11 Aug 2015 15:53:16 +0300 Subject: [PATCH 40/51] STL: Fix another read past EOF --- code/STLLoader.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/code/STLLoader.cpp b/code/STLLoader.cpp index 1bf47dcf2..fc6ca0661 100644 --- a/code/STLLoader.cpp +++ b/code/STLLoader.cpp @@ -304,6 +304,9 @@ void STLImporter::LoadASCIIFile() } else { + if (sz[6] == '\0') { + throw DeadlyImportError("STL: unexpected EOF while parsing facet"); + } sz += 7; SkipSpaces(&sz); sz = fast_atoreal_move(sz, (float&)vn->x ); @@ -324,6 +327,9 @@ void STLImporter::LoadASCIIFile() } else { + if (sz[6] == '\0') { + throw DeadlyImportError("STL: unexpected EOF while parsing facet"); + } sz += 7; SkipSpaces(&sz); positionBuffer.push_back(aiVector3D()); From 5575a54466ea54902c837b9846b44a1c89d777fa Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Tue, 11 Aug 2015 16:09:19 +0300 Subject: [PATCH 41/51] Add various checks to avoid either too large or zero-sized memory allocations --- code/ACLoader.cpp | 10 ++++++++++ code/MD3Loader.cpp | 5 +++++ code/ObjFileImporter.cpp | 5 +++++ 3 files changed, 20 insertions(+) diff --git a/code/ACLoader.cpp b/code/ACLoader.cpp index 642fd5d24..8d2fac171 100644 --- a/code/ACLoader.cpp +++ b/code/ACLoader.cpp @@ -587,9 +587,19 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object, // allocate storage for vertices and normals mesh->mNumFaces = (*cit).first; + if (mesh->mNumFaces == 0) { + throw DeadlyImportError("AC3D: No faces"); + } else if (mesh->mNumFaces > std::numeric_limits::max() / sizeof(aiFace)) { + throw DeadlyImportError("AC3D: Too many faces, would run out of memory"); + } aiFace* faces = mesh->mFaces = new aiFace[mesh->mNumFaces]; mesh->mNumVertices = (*cit).second; + if (mesh->mNumVertices == 0) { + throw DeadlyImportError("AC3D: No vertices"); + } else if (mesh->mNumVertices > std::numeric_limits::max() / sizeof(aiVector3D)) { + throw DeadlyImportError("AC3D: Too many vertices, would run out of memory"); + } aiVector3D* vertices = mesh->mVertices = new aiVector3D[mesh->mNumVertices]; unsigned int cur = 0; diff --git a/code/MD3Loader.cpp b/code/MD3Loader.cpp index f7fafefdd..5e9a1a3dc 100644 --- a/code/MD3Loader.cpp +++ b/code/MD3Loader.cpp @@ -783,6 +783,11 @@ void MD3Importer::InternReadFile( const std::string& pFile, // Allocate output storage pScene->mNumMeshes = pcHeader->NUM_SURFACES; + if (pcHeader->NUM_SURFACES == 0) { + throw DeadlyImportError("MD3: No surfaces"); + } else if (pcHeader->NUM_SURFACES > std::numeric_limits::max() / sizeof(aiMesh)) { + throw DeadlyImportError("MD3: Too many surfaces, would run out of memory"); + } pScene->mMeshes = new aiMesh*[pScene->mNumMeshes]; pScene->mNumMaterials = pcHeader->NUM_SURFACES; diff --git a/code/ObjFileImporter.cpp b/code/ObjFileImporter.cpp index 02232fcd1..7ade10f62 100644 --- a/code/ObjFileImporter.cpp +++ b/code/ObjFileImporter.cpp @@ -380,6 +380,11 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel, // Copy vertices of this mesh instance pMesh->mNumVertices = numIndices; + if (pMesh->mNumVertices == 0) { + throw DeadlyImportError( "OBJ: no vertices" ); + } else if (pMesh->mNumVertices > std::numeric_limits::max() / sizeof(aiVector3D)) { + throw DeadlyImportError( "OBJ: Too many vertices, would run out of memory" ); + } pMesh->mVertices = new aiVector3D[ pMesh->mNumVertices ]; // Allocate buffer for normal vectors From 0b0ba2ec4dd161bfe7a16e6d5133c7e285c5a242 Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Thu, 13 Aug 2015 13:01:49 +0300 Subject: [PATCH 42/51] Refactor logic which checks for too large allocations It's now easier to change the limit --- code/ACLoader.cpp | 6 +++--- code/MD3Loader.cpp | 4 +++- code/ObjFileImporter.cpp | 2 +- include/assimp/defs.h | 8 ++++++++ 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/code/ACLoader.cpp b/code/ACLoader.cpp index 8d2fac171..8e62da442 100644 --- a/code/ACLoader.cpp +++ b/code/ACLoader.cpp @@ -296,7 +296,7 @@ void AC3DImporter::LoadObjectSection(std::vector& objects) SkipSpaces(&buffer); unsigned int t = strtoul10(buffer,&buffer); - if (t >= std::numeric_limits::max() / sizeof(aiVector3D)) { + if (t >= AI_MAX_ALLOC(aiVector3D)) { throw DeadlyImportError("AC3D: Too many vertices, would run out of memory"); } obj.vertices.reserve(t); @@ -589,7 +589,7 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object, mesh->mNumFaces = (*cit).first; if (mesh->mNumFaces == 0) { throw DeadlyImportError("AC3D: No faces"); - } else if (mesh->mNumFaces > std::numeric_limits::max() / sizeof(aiFace)) { + } else if (mesh->mNumFaces > AI_MAX_ALLOC(aiFace)) { throw DeadlyImportError("AC3D: Too many faces, would run out of memory"); } aiFace* faces = mesh->mFaces = new aiFace[mesh->mNumFaces]; @@ -597,7 +597,7 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object, mesh->mNumVertices = (*cit).second; if (mesh->mNumVertices == 0) { throw DeadlyImportError("AC3D: No vertices"); - } else if (mesh->mNumVertices > std::numeric_limits::max() / sizeof(aiVector3D)) { + } else if (mesh->mNumVertices > AI_MAX_ALLOC(aiVector3D)) { throw DeadlyImportError("AC3D: Too many vertices, would run out of memory"); } aiVector3D* vertices = mesh->mVertices = new aiVector3D[mesh->mNumVertices]; diff --git a/code/MD3Loader.cpp b/code/MD3Loader.cpp index 5e9a1a3dc..3852a64a2 100644 --- a/code/MD3Loader.cpp +++ b/code/MD3Loader.cpp @@ -785,7 +785,9 @@ void MD3Importer::InternReadFile( const std::string& pFile, pScene->mNumMeshes = pcHeader->NUM_SURFACES; if (pcHeader->NUM_SURFACES == 0) { throw DeadlyImportError("MD3: No surfaces"); - } else if (pcHeader->NUM_SURFACES > std::numeric_limits::max() / sizeof(aiMesh)) { + } else if (pcHeader->NUM_SURFACES > AI_MAX_ALLOC(aiMesh)) { + // We allocate pointers but check against the size of aiMesh + // since those pointers will eventually have to point to real objects throw DeadlyImportError("MD3: Too many surfaces, would run out of memory"); } pScene->mMeshes = new aiMesh*[pScene->mNumMeshes]; diff --git a/code/ObjFileImporter.cpp b/code/ObjFileImporter.cpp index 7ade10f62..e4046b53b 100644 --- a/code/ObjFileImporter.cpp +++ b/code/ObjFileImporter.cpp @@ -382,7 +382,7 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel, pMesh->mNumVertices = numIndices; if (pMesh->mNumVertices == 0) { throw DeadlyImportError( "OBJ: no vertices" ); - } else if (pMesh->mNumVertices > std::numeric_limits::max() / sizeof(aiVector3D)) { + } else if (pMesh->mNumVertices > AI_MAX_ALLOC(aiVector3D)) { throw DeadlyImportError( "OBJ: Too many vertices, would run out of memory" ); } pMesh->mVertices = new aiVector3D[ pMesh->mNumVertices ]; diff --git a/include/assimp/defs.h b/include/assimp/defs.h index b0954920e..3129a027b 100644 --- a/include/assimp/defs.h +++ b/include/assimp/defs.h @@ -276,4 +276,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # define AI_BUILD_BIG_ENDIAN #endif + +/* To avoid running out of memory + * This can be adjusted for specific use cases + * It's NOT a total limit, just a limit for individual allocations + */ +#define AI_MAX_ALLOC(type) ((256U * 1024 * 1024) / sizeof(type)) + + #endif // !! INCLUDED_AI_DEFINES_H From 4540250116ee27bd571923f620d07f90617cda4c Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Fri, 14 Aug 2015 13:26:45 +0300 Subject: [PATCH 43/51] IFC: Don't store temporary values by reference This is not legal in any way and should never have worked. --- code/IFCOpenings.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/IFCOpenings.cpp b/code/IFCOpenings.cpp index db2187e49..b2a6bf6c5 100644 --- a/code/IFCOpenings.cpp +++ b/code/IFCOpenings.cpp @@ -1227,7 +1227,7 @@ bool GenerateOpenings(std::vector& openings, bool side_flag = true; if (!is_2d_source) { - const IfcVector3& face_nor = ((profile_verts[vi_total+2] - profile_verts[vi_total]) ^ + const IfcVector3 face_nor = ((profile_verts[vi_total+2] - profile_verts[vi_total]) ^ (profile_verts[vi_total+1] - profile_verts[vi_total])).Normalize(); const IfcFloat abs_dot_face_nor = std::abs(nor * face_nor); @@ -1692,7 +1692,7 @@ bool TryAddOpenings_Poly2Tri(const std::vector& openings,const std: BOOST_FOREACH(p2t::Triangle* tri, tris) { for(int i = 0; i < 3; ++i) { - const IfcVector2& v = IfcVector2( + const IfcVector2 v = IfcVector2( static_cast( tri->GetPoint(i)->x ), static_cast( tri->GetPoint(i)->y ) ); From e67bcca744ac854b7631c4e83ad4b968cdb42255 Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Fri, 14 Aug 2015 14:02:16 +0300 Subject: [PATCH 44/51] IFC: Fix more bad references --- code/IFCOpenings.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/code/IFCOpenings.cpp b/code/IFCOpenings.cpp index b2a6bf6c5..d1dd9f50c 100644 --- a/code/IFCOpenings.cpp +++ b/code/IFCOpenings.cpp @@ -602,12 +602,12 @@ bool IntersectingLineSegments(const IfcVector2& n0, const IfcVector2& n1, const IfcVector2& m0, const IfcVector2& m1, IfcVector2& out0, IfcVector2& out1) { - const IfcVector2& n0_to_n1 = n1 - n0; + const IfcVector2 n0_to_n1 = n1 - n0; - const IfcVector2& n0_to_m0 = m0 - n0; - const IfcVector2& n1_to_m1 = m1 - n1; + const IfcVector2 n0_to_m0 = m0 - n0; + const IfcVector2 n1_to_m1 = m1 - n1; - const IfcVector2& n0_to_m1 = m1 - n0; + const IfcVector2 n0_to_m1 = m1 - n0; const IfcFloat e = 1e-5f; const IfcFloat smalle = 1e-9f; @@ -927,7 +927,7 @@ size_t CloseWindows(ContourVector& contours, IfcFloat best = static_cast(1e10); IfcVector3 bestv; - const IfcVector3& world_point = minv * IfcVector3(proj_point.x,proj_point.y,0.0f); + const IfcVector3 world_point = minv * IfcVector3(proj_point.x,proj_point.y,0.0f); BOOST_FOREACH(const TempOpening* opening, refs) { BOOST_FOREACH(const IfcVector3& other, opening->wallPoints) { @@ -1066,7 +1066,7 @@ IfcMatrix4 ProjectOntoPlane(std::vector& out_contour, const TempMesh // Project all points into the new coordinate system, collect min/max verts on the way BOOST_FOREACH(const IfcVector3& x, in_verts) { - const IfcVector3& vv = m * x; + const IfcVector3 vv = m * x; // keep Z offset in the plane coordinate system. Ignoring precision issues // (which are present, of course), this should be the same value for // all polygon vertices (assuming the polygon is planar). @@ -1144,7 +1144,7 @@ bool GenerateOpenings(std::vector& openings, std::vector contour_flat; IfcVector3 nor; - const IfcMatrix4& m = ProjectOntoPlane(contour_flat, curmesh, ok, nor); + const IfcMatrix4 m = ProjectOntoPlane(contour_flat, curmesh, ok, nor); if(!ok) { return false; } @@ -1242,7 +1242,7 @@ bool GenerateOpenings(std::vector& openings, for (unsigned int vi = 0, vend = profile_vertcnts[f]; vi < vend; ++vi, ++vi_total) { const IfcVector3& x = profile_verts[vi_total]; - const IfcVector3& v = m * x; + const IfcVector3 v = m * x; IfcVector2 vv(v.x, v.y); //if(check_intersection) { @@ -1322,7 +1322,7 @@ bool GenerateOpenings(std::vector& openings, MakeDisjunctWindowContours(other, temp_contour, poly); if(poly.size() == 1) { - const BoundingBox& newbb = GetBoundingBox(poly[0].outer); + const BoundingBox newbb = GetBoundingBox(poly[0].outer); if (!BoundingBoxesOverlapping(ibb, newbb )) { // Good guy bounding box bb = newbb ; @@ -1438,7 +1438,7 @@ bool TryAddOpenings_Poly2Tri(const std::vector& openings,const std: // working coordinate system. bool ok; IfcVector3 nor; - const IfcMatrix3& m = DerivePlaneCoordinateSpace(curmesh, ok, nor); + const IfcMatrix3 m = DerivePlaneCoordinateSpace(curmesh, ok, nor); if (!ok) { return false; } @@ -1686,7 +1686,7 @@ bool TryAddOpenings_Poly2Tri(const std::vector& openings,const std: continue; } - const std::vector& tris = cdt->GetTriangles(); + const std::vector tris = cdt->GetTriangles(); // Collect the triangles we just produced BOOST_FOREACH(p2t::Triangle* tri, tris) { From ec43e082959b632764ffaa71519f1bc57247a82f Mon Sep 17 00:00:00 2001 From: Andreas Henne Date: Fri, 14 Aug 2015 13:37:41 +0200 Subject: [PATCH 45/51] Fixed issue in STLLoader that lead to wrong node names. --- code/STLLoader.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/code/STLLoader.cpp b/code/STLLoader.cpp index 1bf47dcf2..a9fe79f27 100644 --- a/code/STLLoader.cpp +++ b/code/STLLoader.cpp @@ -206,7 +206,6 @@ void STLImporter::InternReadFile( const std::string& pFile, } // add all created meshes to the single node - pScene->mRootNode = new aiNode(); pScene->mRootNode->mNumMeshes = pScene->mNumMeshes; pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes]; for (unsigned int i = 0; i < pScene->mNumMeshes; i++) From 9f157ed9b88aeeda56863aebacac37f96fff341c Mon Sep 17 00:00:00 2001 From: Wolfgang Herget Date: Wed, 26 Aug 2015 12:36:57 +0200 Subject: [PATCH 46/51] CMake: Don't try to set property on target before it is defined. The exact same code this commit removes is repeated in line 748. There, it actually works, since the "assimp" target is defined there. --- code/CMakeLists.txt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index 351ce8da2..c3302ee98 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -656,11 +656,6 @@ if ( MSVC ) ADD_DEFINITIONS( -D_CRT_SECURE_NO_WARNINGS ) endif ( MSVC ) -if (APPLE) - SET_TARGET_PROPERTIES( assimp PROPERTIES - INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}" - ) -endif() if (UNZIP_FOUND) SET (unzip_compile_SRCS "") else (UNZIP_FOUND) From 9885c3e55152b350161414cbe970db95ac4f0465 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Fri, 28 Aug 2015 16:20:17 +0200 Subject: [PATCH 47/51] add opencollada extension --- code/ColladaParser.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/code/ColladaParser.cpp b/code/ColladaParser.cpp index ddfab79f1..cdc3cedeb 100644 --- a/code/ColladaParser.cpp +++ b/code/ColladaParser.cpp @@ -1067,6 +1067,12 @@ void ColladaParser::ReadLight( Collada::Light& pLight) pLight.mFalloffAngle = ReadFloatFromTextContent(); TestClosing("hotspot_beam"); } + // OpenCOLLADA extensions + // ------------------------------------------------------- + else if (IsElement("decay_falloff")) { + pLight.mOuterAngle = ReadFloatFromTextContent(); + TestClosing("decay_falloff"); + } } else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { if( strcmp( mReader->getNodeName(), "light") == 0) From 1f6cead81ba463e0104a66ca1d246210196f5267 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Sat, 29 Aug 2015 13:39:43 +0200 Subject: [PATCH 48/51] remove junk --- code/ColladaParser upstream.cpp | 2928 ------------------------------ code/ColladaParser upstream.h | 352 ---- code/ColladaParser wil.cpp | 2933 ------------------------------- 3 files changed, 6213 deletions(-) delete mode 100644 code/ColladaParser upstream.cpp delete mode 100644 code/ColladaParser upstream.h delete mode 100644 code/ColladaParser wil.cpp diff --git a/code/ColladaParser upstream.cpp b/code/ColladaParser upstream.cpp deleted file mode 100644 index d223f8184..000000000 --- a/code/ColladaParser upstream.cpp +++ /dev/null @@ -1,2928 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2015, assimp team - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file ColladaParser.cpp - * @brief Implementation of the Collada parser helper - */ - - -#ifndef ASSIMP_BUILD_NO_COLLADA_IMPORTER - -#include -#include "ColladaParser.h" -#include "fast_atof.h" -#include "ParsingUtils.h" -#include -#include -#include "../include/assimp/DefaultLogger.hpp" -#include "../include/assimp/IOSystem.hpp" -#include "../include/assimp/light.h" - - -using namespace Assimp; -using namespace Assimp::Collada; - -// ------------------------------------------------------------------------------------------------ -// Constructor to be privately used by Importer -ColladaParser::ColladaParser( IOSystem* pIOHandler, const std::string& pFile) - : mFileName( pFile) -{ - mRootNode = NULL; - mUnitSize = 1.0f; - mUpDirection = UP_Y; - - // We assume the newest file format by default - mFormat = FV_1_5_n; - - // open the file - boost::scoped_ptr file( pIOHandler->Open( pFile)); - if( file.get() == NULL) - throw DeadlyImportError( "Failed to open file " + pFile + "."); - - // generate a XML reader for it - boost::scoped_ptr mIOWrapper( new CIrrXML_IOStreamReader( file.get())); - mReader = irr::io::createIrrXMLReader( mIOWrapper.get()); - if( !mReader) - ThrowException( "Collada: Unable to open file."); - - // start reading - ReadContents(); -} - -// ------------------------------------------------------------------------------------------------ -// Destructor, private as well -ColladaParser::~ColladaParser() -{ - delete mReader; - for( NodeLibrary::iterator it = mNodeLibrary.begin(); it != mNodeLibrary.end(); ++it) - delete it->second; - for( MeshLibrary::iterator it = mMeshLibrary.begin(); it != mMeshLibrary.end(); ++it) - delete it->second; -} - -// ------------------------------------------------------------------------------------------------ -// Read bool from text contents of current element -bool ColladaParser::ReadBoolFromTextContent() -{ - const char* cur = GetTextContent(); - return (!ASSIMP_strincmp(cur,"true",4) || '0' != *cur); -} - -// ------------------------------------------------------------------------------------------------ -// Read float from text contents of current element -float ColladaParser::ReadFloatFromTextContent() -{ - const char* cur = GetTextContent(); - return fast_atof(cur); -} - -// ------------------------------------------------------------------------------------------------ -// Reads the contents of the file -void ColladaParser::ReadContents() -{ - while( mReader->read()) - { - // handle the root element "COLLADA" - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - if( IsElement( "COLLADA")) - { - // check for 'version' attribute - const int attrib = TestAttribute("version"); - if (attrib != -1) { - const char* version = mReader->getAttributeValue(attrib); - - if (!::strncmp(version,"1.5",3)) { - mFormat = FV_1_5_n; - DefaultLogger::get()->debug("Collada schema version is 1.5.n"); - } - else if (!::strncmp(version,"1.4",3)) { - mFormat = FV_1_4_n; - DefaultLogger::get()->debug("Collada schema version is 1.4.n"); - } - else if (!::strncmp(version,"1.3",3)) { - mFormat = FV_1_3_n; - DefaultLogger::get()->debug("Collada schema version is 1.3.n"); - } - } - - ReadStructure(); - } else - { - DefaultLogger::get()->debug( boost::str( boost::format( "Ignoring global element <%s>.") % mReader->getNodeName())); - SkipElement(); - } - } else - { - // skip everything else silently - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads the structure of the file -void ColladaParser::ReadStructure() -{ - while( mReader->read()) - { - // beginning of elements - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - if( IsElement( "asset")) - ReadAssetInfo(); - else if( IsElement( "library_animations")) - ReadAnimationLibrary(); - else if( IsElement( "library_controllers")) - ReadControllerLibrary(); - else if( IsElement( "library_images")) - ReadImageLibrary(); - else if( IsElement( "library_materials")) - ReadMaterialLibrary(); - else if( IsElement( "library_effects")) - ReadEffectLibrary(); - else if( IsElement( "library_geometries")) - ReadGeometryLibrary(); - else if( IsElement( "library_visual_scenes")) - ReadSceneLibrary(); - else if( IsElement( "library_lights")) - ReadLightLibrary(); - else if( IsElement( "library_cameras")) - ReadCameraLibrary(); - else if( IsElement( "library_nodes")) - ReadSceneNode(NULL); /* some hacking to reuse this piece of code */ - else if( IsElement( "scene")) - ReadScene(); - else - SkipElement(); - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - { - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads asset informations such as coordinate system informations and legal blah -void ColladaParser::ReadAssetInfo() -{ - if( mReader->isEmptyElement()) - return; - - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - if( IsElement( "unit")) - { - // read unit data from the element's attributes - const int attrIndex = TestAttribute( "meter"); - if (attrIndex == -1) { - mUnitSize = 1.f; - } - else { - mUnitSize = mReader->getAttributeValueAsFloat( attrIndex); - } - - // consume the trailing stuff - if( !mReader->isEmptyElement()) - SkipElement(); - } - else if( IsElement( "up_axis")) - { - // read content, strip whitespace, compare - const char* content = GetTextContent(); - if( strncmp( content, "X_UP", 4) == 0) - mUpDirection = UP_X; - else if( strncmp( content, "Z_UP", 4) == 0) - mUpDirection = UP_Z; - else - mUpDirection = UP_Y; - - // check element end - TestClosing( "up_axis"); - } else - { - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - { - if( strcmp( mReader->getNodeName(), "asset") != 0) - ThrowException( "Expected end of element."); - - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads the animation library -void ColladaParser::ReadAnimationLibrary() -{ - if (mReader->isEmptyElement()) - return; - - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - if( IsElement( "animation")) - { - // delegate the reading. Depending on the inner elements it will be a container or a anim channel - ReadAnimation( &mAnims); - } else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - { - if( strcmp( mReader->getNodeName(), "library_animations") != 0) - ThrowException( "Expected end of element."); - - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads an animation into the given parent structure -void ColladaParser::ReadAnimation( Collada::Animation* pParent) -{ - if( mReader->isEmptyElement()) - return; - - // an element may be a container for grouping sub-elements or an animation channel - // this is the channel collection by ID, in case it has channels - typedef std::map ChannelMap; - ChannelMap channels; - // this is the anim container in case we're a container - Animation* anim = NULL; - - // optional name given as an attribute - std::string animName; - int indexName = TestAttribute( "name"); - int indexID = TestAttribute( "id"); - if( indexName >= 0) - animName = mReader->getAttributeValue( indexName); - else if( indexID >= 0) - animName = mReader->getAttributeValue( indexID); - else - animName = "animation"; - - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - // we have subanimations - if( IsElement( "animation")) - { - // create container from our element - if( !anim) - { - anim = new Animation; - anim->mName = animName; - pParent->mSubAnims.push_back( anim); - } - - // recurse into the subelement - ReadAnimation( anim); - } - else if( IsElement( "source")) - { - // possible animation data - we'll never know. Better store it - ReadSource(); - } - else if( IsElement( "sampler")) - { - // read the ID to assign the corresponding collada channel afterwards. - int indexID = GetAttribute( "id"); - std::string id = mReader->getAttributeValue( indexID); - ChannelMap::iterator newChannel = channels.insert( std::make_pair( id, AnimationChannel())).first; - - // have it read into a channel - ReadAnimationSampler( newChannel->second); - } - else if( IsElement( "channel")) - { - // the binding element whose whole purpose is to provide the target to animate - // Thanks, Collada! A directly posted information would have been too simple, I guess. - // Better add another indirection to that! Can't have enough of those. - int indexTarget = GetAttribute( "target"); - int indexSource = GetAttribute( "source"); - const char* sourceId = mReader->getAttributeValue( indexSource); - if( sourceId[0] == '#') - sourceId++; - ChannelMap::iterator cit = channels.find( sourceId); - if( cit != channels.end()) - cit->second.mTarget = mReader->getAttributeValue( indexTarget); - - if( !mReader->isEmptyElement()) - SkipElement(); - } - else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - { - if( strcmp( mReader->getNodeName(), "animation") != 0) - ThrowException( "Expected end of element."); - - break; - } - } - - // it turned out to have channels - add them - if( !channels.empty()) - { - // special filtering for stupid exporters packing each channel into a separate animation - if( channels.size() == 1) - { - pParent->mChannels.push_back( channels.begin()->second); - } else - { - // else create the animation, if not done yet, and store the channels - if( !anim) - { - anim = new Animation; - anim->mName = animName; - pParent->mSubAnims.push_back( anim); - } - for( ChannelMap::const_iterator it = channels.begin(); it != channels.end(); ++it) - anim->mChannels.push_back( it->second); - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads an animation sampler into the given anim channel -void ColladaParser::ReadAnimationSampler( Collada::AnimationChannel& pChannel) -{ - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - if( IsElement( "input")) - { - int indexSemantic = GetAttribute( "semantic"); - const char* semantic = mReader->getAttributeValue( indexSemantic); - int indexSource = GetAttribute( "source"); - const char* source = mReader->getAttributeValue( indexSource); - if( source[0] != '#') - ThrowException( "Unsupported URL format"); - source++; - - if( strcmp( semantic, "INPUT") == 0) - pChannel.mSourceTimes = source; - else if( strcmp( semantic, "OUTPUT") == 0) - pChannel.mSourceValues = source; - - if( !mReader->isEmptyElement()) - SkipElement(); - } - else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - { - if( strcmp( mReader->getNodeName(), "sampler") != 0) - ThrowException( "Expected end of element."); - - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads the skeleton controller library -void ColladaParser::ReadControllerLibrary() -{ - if (mReader->isEmptyElement()) - return; - - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - if( IsElement( "controller")) - { - // read ID. Ask the spec if it's neccessary or optional... you might be surprised. - int attrID = GetAttribute( "id"); - std::string id = mReader->getAttributeValue( attrID); - - // create an entry and store it in the library under its ID - mControllerLibrary[id] = Controller(); - - // read on from there - ReadController( mControllerLibrary[id]); - } else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - { - if( strcmp( mReader->getNodeName(), "library_controllers") != 0) - ThrowException( "Expected end of element."); - - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads a controller into the given mesh structure -void ColladaParser::ReadController( Collada::Controller& pController) -{ - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - // two types of controllers: "skin" and "morph". Only the first one is relevant, we skip the other - if( IsElement( "morph")) - { - // should skip everything inside, so there's no danger of catching elements inbetween - SkipElement(); - } - else if( IsElement( "skin")) - { - // read the mesh it refers to. According to the spec this could also be another - // controller, but I refuse to implement every single idea they've come up with - int sourceIndex = GetAttribute( "source"); - pController.mMeshId = mReader->getAttributeValue( sourceIndex) + 1; - } - else if( IsElement( "bind_shape_matrix")) - { - // content is 16 floats to define a matrix... it seems to be important for some models - const char* content = GetTextContent(); - - // read the 16 floats - for( unsigned int a = 0; a < 16; a++) - { - // read a number - content = fast_atoreal_move( content, pController.mBindShapeMatrix[a]); - // skip whitespace after it - SkipSpacesAndLineEnd( &content); - } - - TestClosing( "bind_shape_matrix"); - } - else if( IsElement( "source")) - { - // data array - we have specialists to handle this - ReadSource(); - } - else if( IsElement( "joints")) - { - ReadControllerJoints( pController); - } - else if( IsElement( "vertex_weights")) - { - ReadControllerWeights( pController); - } - else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - { - if( strcmp( mReader->getNodeName(), "controller") == 0) - break; - else if( strcmp( mReader->getNodeName(), "skin") != 0) - ThrowException( "Expected end of element."); - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads the joint definitions for the given controller -void ColladaParser::ReadControllerJoints( Collada::Controller& pController) -{ - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - // Input channels for joint data. Two possible semantics: "JOINT" and "INV_BIND_MATRIX" - if( IsElement( "input")) - { - int indexSemantic = GetAttribute( "semantic"); - const char* attrSemantic = mReader->getAttributeValue( indexSemantic); - int indexSource = GetAttribute( "source"); - const char* attrSource = mReader->getAttributeValue( indexSource); - - // local URLS always start with a '#'. We don't support global URLs - if( attrSource[0] != '#') - ThrowException( boost::str( boost::format( "Unsupported URL format in \"%s\" in source attribute of data element") % attrSource)); - attrSource++; - - // parse source URL to corresponding source - if( strcmp( attrSemantic, "JOINT") == 0) - pController.mJointNameSource = attrSource; - else if( strcmp( attrSemantic, "INV_BIND_MATRIX") == 0) - pController.mJointOffsetMatrixSource = attrSource; - else - ThrowException( boost::str( boost::format( "Unknown semantic \"%s\" in data element") % attrSemantic)); - - // skip inner data, if present - if( !mReader->isEmptyElement()) - SkipElement(); - } - else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - { - if( strcmp( mReader->getNodeName(), "joints") != 0) - ThrowException( "Expected end of element."); - - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads the joint weights for the given controller -void ColladaParser::ReadControllerWeights( Collada::Controller& pController) -{ - // read vertex count from attributes and resize the array accordingly - int indexCount = GetAttribute( "count"); - size_t vertexCount = (size_t) mReader->getAttributeValueAsInt( indexCount); - pController.mWeightCounts.resize( vertexCount); - - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - // Input channels for weight data. Two possible semantics: "JOINT" and "WEIGHT" - if( IsElement( "input") && vertexCount > 0 ) - { - InputChannel channel; - - int indexSemantic = GetAttribute( "semantic"); - const char* attrSemantic = mReader->getAttributeValue( indexSemantic); - int indexSource = GetAttribute( "source"); - const char* attrSource = mReader->getAttributeValue( indexSource); - int indexOffset = TestAttribute( "offset"); - if( indexOffset >= 0) - channel.mOffset = mReader->getAttributeValueAsInt( indexOffset); - - // local URLS always start with a '#'. We don't support global URLs - if( attrSource[0] != '#') - ThrowException( boost::str( boost::format( "Unsupported URL format in \"%s\" in source attribute of data element") % attrSource)); - channel.mAccessor = attrSource + 1; - - // parse source URL to corresponding source - if( strcmp( attrSemantic, "JOINT") == 0) - pController.mWeightInputJoints = channel; - else if( strcmp( attrSemantic, "WEIGHT") == 0) - pController.mWeightInputWeights = channel; - else - ThrowException( boost::str( boost::format( "Unknown semantic \"%s\" in data element") % attrSemantic)); - - // skip inner data, if present - if( !mReader->isEmptyElement()) - SkipElement(); - } - else if( IsElement( "vcount") && vertexCount > 0 ) - { - // read weight count per vertex - const char* text = GetTextContent(); - size_t numWeights = 0; - for( std::vector::iterator it = pController.mWeightCounts.begin(); it != pController.mWeightCounts.end(); ++it) - { - if( *text == 0) - ThrowException( "Out of data while reading "); - - *it = strtoul10( text, &text); - numWeights += *it; - SkipSpacesAndLineEnd( &text); - } - - TestClosing( "vcount"); - - // reserve weight count - pController.mWeights.resize( numWeights); - } - else if( IsElement( "v") && vertexCount > 0 ) - { - // read JointIndex - WeightIndex pairs - const char* text = GetTextContent(); - - for( std::vector< std::pair >::iterator it = pController.mWeights.begin(); it != pController.mWeights.end(); ++it) - { - if( *text == 0) - ThrowException( "Out of data while reading "); - it->first = strtoul10( text, &text); - SkipSpacesAndLineEnd( &text); - if( *text == 0) - ThrowException( "Out of data while reading "); - it->second = strtoul10( text, &text); - SkipSpacesAndLineEnd( &text); - } - - TestClosing( "v"); - } - else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - { - if( strcmp( mReader->getNodeName(), "vertex_weights") != 0) - ThrowException( "Expected end of element."); - - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads the image library contents -void ColladaParser::ReadImageLibrary() -{ - if( mReader->isEmptyElement()) - return; - - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) { - if( IsElement( "image")) - { - // read ID. Another entry which is "optional" by design but obligatory in reality - int attrID = GetAttribute( "id"); - std::string id = mReader->getAttributeValue( attrID); - - // create an entry and store it in the library under its ID - mImageLibrary[id] = Image(); - - // read on from there - ReadImage( mImageLibrary[id]); - } else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { - if( strcmp( mReader->getNodeName(), "library_images") != 0) - ThrowException( "Expected end of element."); - - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads an image entry into the given image -void ColladaParser::ReadImage( Collada::Image& pImage) -{ - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT){ - // Need to run different code paths here, depending on the Collada XSD version - if (IsElement("image")) { - SkipElement(); - } - else if( IsElement( "init_from")) - { - if (mFormat == FV_1_4_n) - { - // FIX: C4D exporter writes empty tags - if (!mReader->isEmptyElement()) { - // element content is filename - hopefully - const char* sz = TestTextContent(); - if (sz)pImage.mFileName = sz; - TestClosing( "init_from"); - } - if (!pImage.mFileName.length()) { - pImage.mFileName = "unknown_texture"; - } - } - else if (mFormat == FV_1_5_n) - { - // make sure we skip over mip and array initializations, which - // we don't support, but which could confuse the loader if - // they're not skipped. - int attrib = TestAttribute("array_index"); - if (attrib != -1 && mReader->getAttributeValueAsInt(attrib) > 0) { - DefaultLogger::get()->warn("Collada: Ignoring texture array index"); - continue; - } - - attrib = TestAttribute("mip_index"); - if (attrib != -1 && mReader->getAttributeValueAsInt(attrib) > 0) { - DefaultLogger::get()->warn("Collada: Ignoring MIP map layer"); - continue; - } - - // TODO: correctly jump over cube and volume maps? - } - } - else if (mFormat == FV_1_5_n) - { - if( IsElement( "ref")) - { - // element content is filename - hopefully - const char* sz = TestTextContent(); - if (sz)pImage.mFileName = sz; - TestClosing( "ref"); - } - else if( IsElement( "hex") && !pImage.mFileName.length()) - { - // embedded image. get format - const int attrib = TestAttribute("format"); - if (-1 == attrib) - DefaultLogger::get()->warn("Collada: Unknown image file format"); - else pImage.mEmbeddedFormat = mReader->getAttributeValue(attrib); - - const char* data = GetTextContent(); - - // hexadecimal-encoded binary octets. First of all, find the - // required buffer size to reserve enough storage. - const char* cur = data; - while (!IsSpaceOrNewLine(*cur)) cur++; - - const unsigned int size = (unsigned int)(cur-data) * 2; - pImage.mImageData.resize(size); - for (unsigned int i = 0; i < size;++i) - pImage.mImageData[i] = HexOctetToDecimal(data+(i<<1)); - - TestClosing( "hex"); - } - } - else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { - if( strcmp( mReader->getNodeName(), "image") == 0) - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads the material library -void ColladaParser::ReadMaterialLibrary() -{ - if( mReader->isEmptyElement()) - return; - - std::map names; - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - if( IsElement( "material")) - { - // read ID. By now you propably know my opinion about this "specification" - int attrID = GetAttribute( "id"); - std::string id = mReader->getAttributeValue( attrID); - - std::string name; - int attrName = TestAttribute("name"); - if (attrName >= 0) - name = mReader->getAttributeValue( attrName); - - // create an entry and store it in the library under its ID - mMaterialLibrary[id] = Material(); - - if( !name.empty()) - { - std::map::iterator it = names.find( name); - if( it != names.end()) - { - std::ostringstream strStream; - strStream << ++it->second; - name.append( " " + strStream.str()); - } - else - { - names[name] = 0; - } - - mMaterialLibrary[id].mName = name; - } - - ReadMaterial( mMaterialLibrary[id]); - } else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - { - if( strcmp( mReader->getNodeName(), "library_materials") != 0) - ThrowException( "Expected end of element."); - - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads the light library -void ColladaParser::ReadLightLibrary() -{ - if( mReader->isEmptyElement()) - return; - - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) { - if( IsElement( "light")) - { - // read ID. By now you propably know my opinion about this "specification" - int attrID = GetAttribute( "id"); - std::string id = mReader->getAttributeValue( attrID); - - // create an entry and store it in the library under its ID - ReadLight(mLightLibrary[id] = Light()); - - } else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { - if( strcmp( mReader->getNodeName(), "library_lights") != 0) - ThrowException( "Expected end of element."); - - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads the camera library -void ColladaParser::ReadCameraLibrary() -{ - if( mReader->isEmptyElement()) - return; - - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) { - if( IsElement( "camera")) - { - // read ID. By now you propably know my opinion about this "specification" - int attrID = GetAttribute( "id"); - std::string id = mReader->getAttributeValue( attrID); - - // create an entry and store it in the library under its ID - Camera& cam = mCameraLibrary[id]; - attrID = TestAttribute( "name"); - if (attrID != -1) - cam.mName = mReader->getAttributeValue( attrID); - - ReadCamera(cam); - - } else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { - if( strcmp( mReader->getNodeName(), "library_cameras") != 0) - ThrowException( "Expected end of element."); - - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads a material entry into the given material -void ColladaParser::ReadMaterial( Collada::Material& pMaterial) -{ - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) { - if (IsElement("material")) { - SkipElement(); - } - else if( IsElement( "instance_effect")) - { - // referred effect by URL - int attrUrl = GetAttribute( "url"); - const char* url = mReader->getAttributeValue( attrUrl); - if( url[0] != '#') - ThrowException( "Unknown reference format"); - - pMaterial.mEffect = url+1; - - SkipElement(); - } else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { - if( strcmp( mReader->getNodeName(), "material") != 0) - ThrowException( "Expected end of element."); - - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads a light entry into the given light -void ColladaParser::ReadLight( Collada::Light& pLight) -{ - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) { - if (IsElement("light")) { - SkipElement(); - } - else if (IsElement("spot")) { - pLight.mType = aiLightSource_SPOT; - } - else if (IsElement("ambient")) { - pLight.mType = aiLightSource_AMBIENT; - } - else if (IsElement("directional")) { - pLight.mType = aiLightSource_DIRECTIONAL; - } - else if (IsElement("point")) { - pLight.mType = aiLightSource_POINT; - } - else if (IsElement("color")) { - // text content contains 3 floats - const char* content = GetTextContent(); - - content = fast_atoreal_move( content, (float&)pLight.mColor.r); - SkipSpacesAndLineEnd( &content); - - content = fast_atoreal_move( content, (float&)pLight.mColor.g); - SkipSpacesAndLineEnd( &content); - - content = fast_atoreal_move( content, (float&)pLight.mColor.b); - SkipSpacesAndLineEnd( &content); - - TestClosing( "color"); - } - else if (IsElement("constant_attenuation")) { - pLight.mAttConstant = ReadFloatFromTextContent(); - TestClosing("constant_attenuation"); - } - else if (IsElement("linear_attenuation")) { - pLight.mAttLinear = ReadFloatFromTextContent(); - TestClosing("linear_attenuation"); - } - else if (IsElement("quadratic_attenuation")) { - pLight.mAttQuadratic = ReadFloatFromTextContent(); - TestClosing("quadratic_attenuation"); - } - else if (IsElement("falloff_angle")) { - pLight.mFalloffAngle = ReadFloatFromTextContent(); - TestClosing("falloff_angle"); - } - else if (IsElement("falloff_exponent")) { - pLight.mFalloffExponent = ReadFloatFromTextContent(); - TestClosing("falloff_exponent"); - } - // FCOLLADA extensions - // ------------------------------------------------------- - else if (IsElement("outer_cone")) { - pLight.mOuterAngle = ReadFloatFromTextContent(); - TestClosing("outer_cone"); - } - // ... and this one is even deprecated - else if (IsElement("penumbra_angle")) { - pLight.mPenumbraAngle = ReadFloatFromTextContent(); - TestClosing("penumbra_angle"); - } - else if (IsElement("intensity")) { - pLight.mIntensity = ReadFloatFromTextContent(); - TestClosing("intensity"); - } - else if (IsElement("falloff")) { - pLight.mOuterAngle = ReadFloatFromTextContent(); - TestClosing("falloff"); - } - else if (IsElement("hotspot_beam")) { - pLight.mFalloffAngle = ReadFloatFromTextContent(); - TestClosing("hotspot_beam"); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { - if( strcmp( mReader->getNodeName(), "light") == 0) - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads a camera entry into the given light -void ColladaParser::ReadCamera( Collada::Camera& pCamera) -{ - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) { - if (IsElement("camera")) { - SkipElement(); - } - else if (IsElement("orthographic")) { - pCamera.mOrtho = true; - } - else if (IsElement("xfov") || IsElement("xmag")) { - pCamera.mHorFov = ReadFloatFromTextContent(); - TestClosing((pCamera.mOrtho ? "xmag" : "xfov")); - } - else if (IsElement("yfov") || IsElement("ymag")) { - pCamera.mVerFov = ReadFloatFromTextContent(); - TestClosing((pCamera.mOrtho ? "ymag" : "yfov")); - } - else if (IsElement("aspect_ratio")) { - pCamera.mAspect = ReadFloatFromTextContent(); - TestClosing("aspect_ratio"); - } - else if (IsElement("znear")) { - pCamera.mZNear = ReadFloatFromTextContent(); - TestClosing("znear"); - } - else if (IsElement("zfar")) { - pCamera.mZFar = ReadFloatFromTextContent(); - TestClosing("zfar"); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { - if( strcmp( mReader->getNodeName(), "camera") == 0) - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads the effect library -void ColladaParser::ReadEffectLibrary() -{ - if (mReader->isEmptyElement()) { - return; - } - - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) { - if( IsElement( "effect")) - { - // read ID. Do I have to repeat my ranting about "optional" attributes? - int attrID = GetAttribute( "id"); - std::string id = mReader->getAttributeValue( attrID); - - // create an entry and store it in the library under its ID - mEffectLibrary[id] = Effect(); - // read on from there - ReadEffect( mEffectLibrary[id]); - } else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { - if( strcmp( mReader->getNodeName(), "library_effects") != 0) - ThrowException( "Expected end of element."); - - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads an effect entry into the given effect -void ColladaParser::ReadEffect( Collada::Effect& pEffect) -{ - // for the moment we don't support any other type of effect. - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - if( IsElement( "profile_COMMON")) - ReadEffectProfileCommon( pEffect); - else - SkipElement(); - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - { - if( strcmp( mReader->getNodeName(), "effect") != 0) - ThrowException( "Expected end of element."); - - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads an COMMON effect profile -void ColladaParser::ReadEffectProfileCommon( Collada::Effect& pEffect) -{ - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - if( IsElement( "newparam")) { - // save ID - int attrSID = GetAttribute( "sid"); - std::string sid = mReader->getAttributeValue( attrSID); - pEffect.mParams[sid] = EffectParam(); - ReadEffectParam( pEffect.mParams[sid]); - } - else if( IsElement( "technique") || IsElement( "extra")) - { - // just syntactic sugar - } - - else if( mFormat == FV_1_4_n && IsElement( "image")) - { - // read ID. Another entry which is "optional" by design but obligatory in reality - int attrID = GetAttribute( "id"); - std::string id = mReader->getAttributeValue( attrID); - - // create an entry and store it in the library under its ID - mImageLibrary[id] = Image(); - - // read on from there - ReadImage( mImageLibrary[id]); - } - - /* Shading modes */ - else if( IsElement( "phong")) - pEffect.mShadeType = Shade_Phong; - else if( IsElement( "constant")) - pEffect.mShadeType = Shade_Constant; - else if( IsElement( "lambert")) - pEffect.mShadeType = Shade_Lambert; - else if( IsElement( "blinn")) - pEffect.mShadeType = Shade_Blinn; - - /* Color + texture properties */ - else if( IsElement( "emission")) - ReadEffectColor( pEffect.mEmissive, pEffect.mTexEmissive); - else if( IsElement( "ambient")) - ReadEffectColor( pEffect.mAmbient, pEffect.mTexAmbient); - else if( IsElement( "diffuse")) - ReadEffectColor( pEffect.mDiffuse, pEffect.mTexDiffuse); - else if( IsElement( "specular")) - ReadEffectColor( pEffect.mSpecular, pEffect.mTexSpecular); - else if( IsElement( "reflective")) { - ReadEffectColor( pEffect.mReflective, pEffect.mTexReflective); - } - else if( IsElement( "transparent")) { - pEffect.mHasTransparency = true; - - // In RGB_ZERO mode, the transparency is interpreted in reverse, go figure... - if(::strcmp(mReader->getAttributeValueSafe("opaque"), "RGB_ZERO") == 0) { - // TODO: handle RGB_ZERO mode completely - pEffect.mRGBTransparency = true; - } - - ReadEffectColor( pEffect.mTransparent,pEffect.mTexTransparent); - } - else if( IsElement( "shininess")) - ReadEffectFloat( pEffect.mShininess); - else if( IsElement( "reflectivity")) - ReadEffectFloat( pEffect.mReflectivity); - - /* Single scalar properties */ - else if( IsElement( "transparency")) - ReadEffectFloat( pEffect.mTransparency); - else if( IsElement( "index_of_refraction")) - ReadEffectFloat( pEffect.mRefractIndex); - - // GOOGLEEARTH/OKINO extensions - // ------------------------------------------------------- - else if( IsElement( "double_sided")) - pEffect.mDoubleSided = ReadBoolFromTextContent(); - - // FCOLLADA extensions - // ------------------------------------------------------- - else if( IsElement( "bump")) { - aiColor4D dummy; - ReadEffectColor( dummy,pEffect.mTexBump); - } - - // MAX3D extensions - // ------------------------------------------------------- - else if( IsElement( "wireframe")) { - pEffect.mWireframe = ReadBoolFromTextContent(); - TestClosing( "wireframe"); - } - else if( IsElement( "faceted")) { - pEffect.mFaceted = ReadBoolFromTextContent(); - TestClosing( "faceted"); - } - else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { - if( strcmp( mReader->getNodeName(), "profile_COMMON") == 0) - { - break; - } - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Read texture wrapping + UV transform settings from a profile==Maya chunk -void ColladaParser::ReadSamplerProperties( Sampler& out ) -{ - if (mReader->isEmptyElement()) { - return; - } - - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) { - - // MAYA extensions - // ------------------------------------------------------- - if( IsElement( "wrapU")) { - out.mWrapU = ReadBoolFromTextContent(); - TestClosing( "wrapU"); - } - else if( IsElement( "wrapV")) { - out.mWrapV = ReadBoolFromTextContent(); - TestClosing( "wrapV"); - } - else if( IsElement( "mirrorU")) { - out.mMirrorU = ReadBoolFromTextContent(); - TestClosing( "mirrorU"); - } - else if( IsElement( "mirrorV")) { - out.mMirrorV = ReadBoolFromTextContent(); - TestClosing( "mirrorV"); - } - else if( IsElement( "repeatU")) { - out.mTransform.mScaling.x = ReadFloatFromTextContent(); - TestClosing( "repeatU"); - } - else if( IsElement( "repeatV")) { - out.mTransform.mScaling.y = ReadFloatFromTextContent(); - TestClosing( "repeatV"); - } - else if( IsElement( "offsetU")) { - out.mTransform.mTranslation.x = ReadFloatFromTextContent(); - TestClosing( "offsetU"); - } - else if( IsElement( "offsetV")) { - out.mTransform.mTranslation.y = ReadFloatFromTextContent(); - TestClosing( "offsetV"); - } - else if( IsElement( "rotateUV")) { - out.mTransform.mRotation = ReadFloatFromTextContent(); - TestClosing( "rotateUV"); - } - else if( IsElement( "blend_mode")) { - - const char* sz = GetTextContent(); - // http://www.feelingsoftware.com/content/view/55/72/lang,en/ - // NONE, OVER, IN, OUT, ADD, SUBTRACT, MULTIPLY, DIFFERENCE, LIGHTEN, DARKEN, SATURATE, DESATURATE and ILLUMINATE - if (0 == ASSIMP_strincmp(sz,"ADD",3)) - out.mOp = aiTextureOp_Add; - - else if (0 == ASSIMP_strincmp(sz,"SUBTRACT",8)) - out.mOp = aiTextureOp_Subtract; - - else if (0 == ASSIMP_strincmp(sz,"MULTIPLY",8)) - out.mOp = aiTextureOp_Multiply; - - else { - DefaultLogger::get()->warn("Collada: Unsupported MAYA texture blend mode"); - } - TestClosing( "blend_mode"); - } - // OKINO extensions - // ------------------------------------------------------- - else if( IsElement( "weighting")) { - out.mWeighting = ReadFloatFromTextContent(); - TestClosing( "weighting"); - } - else if( IsElement( "mix_with_previous_layer")) { - out.mMixWithPrevious = ReadFloatFromTextContent(); - TestClosing( "mix_with_previous_layer"); - } - // MAX3D extensions - // ------------------------------------------------------- - else if( IsElement( "amount")) { - out.mWeighting = ReadFloatFromTextContent(); - TestClosing( "amount"); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { - if( strcmp( mReader->getNodeName(), "technique") == 0) - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads an effect entry containing a color or a texture defining that color -void ColladaParser::ReadEffectColor( aiColor4D& pColor, Sampler& pSampler) -{ - if (mReader->isEmptyElement()) - return; - - // Save current element name - const std::string curElem = mReader->getNodeName(); - - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) { - if( IsElement( "color")) - { - // text content contains 4 floats - const char* content = GetTextContent(); - - content = fast_atoreal_move( content, (float&)pColor.r); - SkipSpacesAndLineEnd( &content); - - content = fast_atoreal_move( content, (float&)pColor.g); - SkipSpacesAndLineEnd( &content); - - content = fast_atoreal_move( content, (float&)pColor.b); - SkipSpacesAndLineEnd( &content); - - content = fast_atoreal_move( content, (float&)pColor.a); - SkipSpacesAndLineEnd( &content); - TestClosing( "color"); - } - else if( IsElement( "texture")) - { - // get name of source textur/sampler - int attrTex = GetAttribute( "texture"); - pSampler.mName = mReader->getAttributeValue( attrTex); - - // get name of UV source channel. Specification demands it to be there, but some exporters - // don't write it. It will be the default UV channel in case it's missing. - attrTex = TestAttribute( "texcoord"); - if( attrTex >= 0 ) - pSampler.mUVChannel = mReader->getAttributeValue( attrTex); - //SkipElement(); - - // as we've read texture, the color needs to be 1,1,1,1 - pColor = aiColor4D(1.f, 1.f, 1.f, 1.f); - } - else if( IsElement( "technique")) - { - const int _profile = GetAttribute( "profile"); - const char* profile = mReader->getAttributeValue( _profile ); - - // Some extensions are quite useful ... ReadSamplerProperties processes - // several extensions in MAYA, OKINO and MAX3D profiles. - if (!::strcmp(profile,"MAYA") || !::strcmp(profile,"MAX3D") || !::strcmp(profile,"OKINO")) - { - // get more information on this sampler - ReadSamplerProperties(pSampler); - } - else SkipElement(); - } - else if( !IsElement( "extra")) - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END){ - if (mReader->getNodeName() == curElem) - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads an effect entry containing a float -void ColladaParser::ReadEffectFloat( float& pFloat) -{ - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT){ - if( IsElement( "float")) - { - // text content contains a single floats - const char* content = GetTextContent(); - content = fast_atoreal_move( content, pFloat); - SkipSpacesAndLineEnd( &content); - - TestClosing( "float"); - } else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END){ - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads an effect parameter specification of any kind -void ColladaParser::ReadEffectParam( Collada::EffectParam& pParam) -{ - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) { - if( IsElement( "surface")) - { - // image ID given inside tags - TestOpening( "init_from"); - const char* content = GetTextContent(); - pParam.mType = Param_Surface; - pParam.mReference = content; - TestClosing( "init_from"); - - // don't care for remaining stuff - SkipElement( "surface"); - } - else if( IsElement( "sampler2D")) - { - // surface ID is given inside tags - TestOpening( "source"); - const char* content = GetTextContent(); - pParam.mType = Param_Sampler; - pParam.mReference = content; - TestClosing( "source"); - - // don't care for remaining stuff - SkipElement( "sampler2D"); - } else - { - // ignore unknown element - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads the geometry library contents -void ColladaParser::ReadGeometryLibrary() -{ - if( mReader->isEmptyElement()) - return; - - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - if( IsElement( "geometry")) - { - // read ID. Another entry which is "optional" by design but obligatory in reality - int indexID = GetAttribute( "id"); - std::string id = mReader->getAttributeValue( indexID); - - // TODO: (thom) support SIDs - // ai_assert( TestAttribute( "sid") == -1); - - // create a mesh and store it in the library under its ID - Mesh* mesh = new Mesh; - mMeshLibrary[id] = mesh; - - // read the mesh name if it exists - const int nameIndex = TestAttribute("name"); - if(nameIndex != -1) - { - mesh->mName = mReader->getAttributeValue(nameIndex); - } - - // read on from there - ReadGeometry( mesh); - } else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - { - if( strcmp( mReader->getNodeName(), "library_geometries") != 0) - ThrowException( "Expected end of element."); - - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads a geometry from the geometry library. -void ColladaParser::ReadGeometry( Collada::Mesh* pMesh) -{ - if( mReader->isEmptyElement()) - return; - - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - if( IsElement( "mesh")) - { - // read on from there - ReadMesh( pMesh); - } else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - { - if( strcmp( mReader->getNodeName(), "geometry") != 0) - ThrowException( "Expected end of element."); - - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads a mesh from the geometry library -void ColladaParser::ReadMesh( Mesh* pMesh) -{ - if( mReader->isEmptyElement()) - return; - - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - if( IsElement( "source")) - { - // we have professionals dealing with this - ReadSource(); - } - else if( IsElement( "vertices")) - { - // read per-vertex mesh data - ReadVertexData( pMesh); - } - else if( IsElement( "triangles") || IsElement( "lines") || IsElement( "linestrips") - || IsElement( "polygons") || IsElement( "polylist") || IsElement( "trifans") || IsElement( "tristrips")) - { - // read per-index mesh data and faces setup - ReadIndexData( pMesh); - } else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - { - if( strcmp( mReader->getNodeName(), "technique_common") == 0) - { - // end of another meaningless element - read over it - } - else if( strcmp( mReader->getNodeName(), "mesh") == 0) - { - // end of element - we're done here - break; - } else - { - // everything else should be punished - ThrowException( "Expected end of element."); - } - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads a source element -void ColladaParser::ReadSource() -{ - int indexID = GetAttribute( "id"); - std::string sourceID = mReader->getAttributeValue( indexID); - - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - if( IsElement( "float_array") || IsElement( "IDREF_array") || IsElement( "Name_array")) - { - ReadDataArray(); - } - else if( IsElement( "technique_common")) - { - // I don't care for your profiles - } - else if( IsElement( "accessor")) - { - ReadAccessor( sourceID); - } else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - { - if( strcmp( mReader->getNodeName(), "source") == 0) - { - // end of - we're done - break; - } - else if( strcmp( mReader->getNodeName(), "technique_common") == 0) - { - // end of another meaningless element - read over it - } else - { - // everything else should be punished - ThrowException( "Expected end of element."); - } - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads a data array holding a number of floats, and stores it in the global library -void ColladaParser::ReadDataArray() -{ - std::string elmName = mReader->getNodeName(); - bool isStringArray = (elmName == "IDREF_array" || elmName == "Name_array"); - bool isEmptyElement = mReader->isEmptyElement(); - - // read attributes - int indexID = GetAttribute( "id"); - std::string id = mReader->getAttributeValue( indexID); - int indexCount = GetAttribute( "count"); - unsigned int count = (unsigned int) mReader->getAttributeValueAsInt( indexCount); - const char* content = TestTextContent(); - - // read values and store inside an array in the data library - mDataLibrary[id] = Data(); - Data& data = mDataLibrary[id]; - data.mIsStringArray = isStringArray; - - // some exporters write empty data arrays, but we need to conserve them anyways because others might reference them - if (content) - { - if( isStringArray) - { - data.mStrings.reserve( count); - std::string s; - - for( unsigned int a = 0; a < count; a++) - { - if( *content == 0) - ThrowException( "Expected more values while reading IDREF_array contents."); - - s.clear(); - while( !IsSpaceOrNewLine( *content)) - s += *content++; - data.mStrings.push_back( s); - - SkipSpacesAndLineEnd( &content); - } - } else - { - data.mValues.reserve( count); - - for( unsigned int a = 0; a < count; a++) - { - if( *content == 0) - ThrowException( "Expected more values while reading float_array contents."); - - float value; - // read a number - content = fast_atoreal_move( content, value); - data.mValues.push_back( value); - // skip whitespace after it - SkipSpacesAndLineEnd( &content); - } - } - } - - // test for closing tag - if( !isEmptyElement ) - TestClosing( elmName.c_str()); -} - -// ------------------------------------------------------------------------------------------------ -// Reads an accessor and stores it in the global library -void ColladaParser::ReadAccessor( const std::string& pID) -{ - // read accessor attributes - int attrSource = GetAttribute( "source"); - const char* source = mReader->getAttributeValue( attrSource); - if( source[0] != '#') - ThrowException( boost::str( boost::format( "Unknown reference format in url \"%s\" in source attribute of element.") % source)); - int attrCount = GetAttribute( "count"); - unsigned int count = (unsigned int) mReader->getAttributeValueAsInt( attrCount); - int attrOffset = TestAttribute( "offset"); - unsigned int offset = 0; - if( attrOffset > -1) - offset = (unsigned int) mReader->getAttributeValueAsInt( attrOffset); - int attrStride = TestAttribute( "stride"); - unsigned int stride = 1; - if( attrStride > -1) - stride = (unsigned int) mReader->getAttributeValueAsInt( attrStride); - - // store in the library under the given ID - mAccessorLibrary[pID] = Accessor(); - Accessor& acc = mAccessorLibrary[pID]; - acc.mCount = count; - acc.mOffset = offset; - acc.mStride = stride; - acc.mSource = source+1; // ignore the leading '#' - acc.mSize = 0; // gets incremented with every param - - // and read the components - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - if( IsElement( "param")) - { - // read data param - int attrName = TestAttribute( "name"); - std::string name; - if( attrName > -1) - { - name = mReader->getAttributeValue( attrName); - - // analyse for common type components and store it's sub-offset in the corresponding field - - /* Cartesian coordinates */ - if( name == "X") acc.mSubOffset[0] = acc.mParams.size(); - else if( name == "Y") acc.mSubOffset[1] = acc.mParams.size(); - else if( name == "Z") acc.mSubOffset[2] = acc.mParams.size(); - - /* RGBA colors */ - else if( name == "R") acc.mSubOffset[0] = acc.mParams.size(); - else if( name == "G") acc.mSubOffset[1] = acc.mParams.size(); - else if( name == "B") acc.mSubOffset[2] = acc.mParams.size(); - else if( name == "A") acc.mSubOffset[3] = acc.mParams.size(); - - /* UVWQ (STPQ) texture coordinates */ - else if( name == "S") acc.mSubOffset[0] = acc.mParams.size(); - else if( name == "T") acc.mSubOffset[1] = acc.mParams.size(); - else if( name == "P") acc.mSubOffset[2] = acc.mParams.size(); - // else if( name == "Q") acc.mSubOffset[3] = acc.mParams.size(); - /* 4D uv coordinates are not supported in Assimp */ - - /* Generic extra data, interpreted as UV data, too*/ - else if( name == "U") acc.mSubOffset[0] = acc.mParams.size(); - else if( name == "V") acc.mSubOffset[1] = acc.mParams.size(); - //else - // DefaultLogger::get()->warn( boost::str( boost::format( "Unknown accessor parameter \"%s\". Ignoring data channel.") % name)); - } - - // read data type - int attrType = TestAttribute( "type"); - if( attrType > -1) - { - // for the moment we only distinguish between a 4x4 matrix and anything else. - // TODO: (thom) I don't have a spec here at work. Check if there are other multi-value types - // which should be tested for here. - std::string type = mReader->getAttributeValue( attrType); - if( type == "float4x4") - acc.mSize += 16; - else - acc.mSize += 1; - } - - acc.mParams.push_back( name); - - // skip remaining stuff of this element, if any - SkipElement(); - } else - { - ThrowException( boost::str( boost::format( "Unexpected sub element <%s> in tag ") % mReader->getNodeName())); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - { - if( strcmp( mReader->getNodeName(), "accessor") != 0) - ThrowException( "Expected end of element."); - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads input declarations of per-vertex mesh data into the given mesh -void ColladaParser::ReadVertexData( Mesh* pMesh) -{ - // extract the ID of the element. Not that we care, but to catch strange referencing schemes we should warn about - int attrID= GetAttribute( "id"); - pMesh->mVertexID = mReader->getAttributeValue( attrID); - - // a number of elements - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - if( IsElement( "input")) - { - ReadInputChannel( pMesh->mPerVertexData); - } else - { - ThrowException( boost::str( boost::format( "Unexpected sub element <%s> in tag ") % mReader->getNodeName())); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - { - if( strcmp( mReader->getNodeName(), "vertices") != 0) - ThrowException( "Expected end of element."); - - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads input declarations of per-index mesh data into the given mesh -void ColladaParser::ReadIndexData( Mesh* pMesh) -{ - std::vector vcount; - std::vector perIndexData; - - // read primitive count from the attribute - int attrCount = GetAttribute( "count"); - size_t numPrimitives = (size_t) mReader->getAttributeValueAsInt( attrCount); - // some mesh types (e.g. tristrips) don't specify primitive count upfront, - // so we need to sum up the actual number of primitives while we read the

-tags - size_t actualPrimitives = 0; - - // material subgroup - int attrMaterial = TestAttribute( "material"); - SubMesh subgroup; - if( attrMaterial > -1) - subgroup.mMaterial = mReader->getAttributeValue( attrMaterial); - - // distinguish between polys and triangles - std::string elementName = mReader->getNodeName(); - PrimitiveType primType = Prim_Invalid; - if( IsElement( "lines")) - primType = Prim_Lines; - else if( IsElement( "linestrips")) - primType = Prim_LineStrip; - else if( IsElement( "polygons")) - primType = Prim_Polygon; - else if( IsElement( "polylist")) - primType = Prim_Polylist; - else if( IsElement( "triangles")) - primType = Prim_Triangles; - else if( IsElement( "trifans")) - primType = Prim_TriFans; - else if( IsElement( "tristrips")) - primType = Prim_TriStrips; - - ai_assert( primType != Prim_Invalid); - - // also a number of elements, but in addition a

primitive collection and propably index counts for all primitives - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - if( IsElement( "input")) - { - ReadInputChannel( perIndexData); - } - else if( IsElement( "vcount")) - { - if( !mReader->isEmptyElement()) - { - if (numPrimitives) // It is possible to define a mesh without any primitives - { - // case - specifies the number of indices for each polygon - const char* content = GetTextContent(); - vcount.reserve( numPrimitives); - for( unsigned int a = 0; a < numPrimitives; a++) - { - if( *content == 0) - ThrowException( "Expected more values while reading contents."); - // read a number - vcount.push_back( (size_t) strtoul10( content, &content)); - // skip whitespace after it - SkipSpacesAndLineEnd( &content); - } - } - - TestClosing( "vcount"); - } - } - else if( IsElement( "p")) - { - if( !mReader->isEmptyElement()) - { - // now here the actual fun starts - these are the indices to construct the mesh data from - actualPrimitives += ReadPrimitives(pMesh, perIndexData, numPrimitives, vcount, primType); - } - } - else if (IsElement("extra")) - { - SkipElement("extra"); - } else - { - ThrowException( boost::str( boost::format( "Unexpected sub element <%s> in tag <%s>") % mReader->getNodeName() % elementName)); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - { - if( mReader->getNodeName() != elementName) - ThrowException( boost::str( boost::format( "Expected end of <%s> element.") % elementName)); - - break; - } - } - -#ifdef ASSIMP_BUILD_DEBUG - if (primType != Prim_TriFans && primType != Prim_TriStrips) { - ai_assert(actualPrimitives == numPrimitives); - } -#endif - - // only when we're done reading all

tags (and thus know the final vertex count) can we commit the submesh - subgroup.mNumFaces = actualPrimitives; - pMesh->mSubMeshes.push_back(subgroup); -} - -// ------------------------------------------------------------------------------------------------ -// Reads a single input channel element and stores it in the given array, if valid -void ColladaParser::ReadInputChannel( std::vector& poChannels) -{ - InputChannel channel; - - // read semantic - int attrSemantic = GetAttribute( "semantic"); - std::string semantic = mReader->getAttributeValue( attrSemantic); - channel.mType = GetTypeForSemantic( semantic); - - // read source - int attrSource = GetAttribute( "source"); - const char* source = mReader->getAttributeValue( attrSource); - if( source[0] != '#') - ThrowException( boost::str( boost::format( "Unknown reference format in url \"%s\" in source attribute of element.") % source)); - channel.mAccessor = source+1; // skipping the leading #, hopefully the remaining text is the accessor ID only - - // read index offset, if per-index - int attrOffset = TestAttribute( "offset"); - if( attrOffset > -1) - channel.mOffset = mReader->getAttributeValueAsInt( attrOffset); - - // read set if texture coordinates - if(channel.mType == IT_Texcoord || channel.mType == IT_Color){ - int attrSet = TestAttribute("set"); - if(attrSet > -1){ - attrSet = mReader->getAttributeValueAsInt( attrSet); - if(attrSet < 0) - ThrowException( boost::str( boost::format( "Invalid index \"%i\" in set attribute of element") % (attrSet))); - - channel.mIndex = attrSet; - } - } - - // store, if valid type - if( channel.mType != IT_Invalid) - poChannels.push_back( channel); - - // skip remaining stuff of this element, if any - SkipElement(); -} - -// ------------------------------------------------------------------------------------------------ -// Reads a

primitive index list and assembles the mesh data into the given mesh -size_t ColladaParser::ReadPrimitives( Mesh* pMesh, std::vector& pPerIndexChannels, - size_t pNumPrimitives, const std::vector& pVCount, PrimitiveType pPrimType) -{ - // determine number of indices coming per vertex - // find the offset index for all per-vertex channels - size_t numOffsets = 1; - size_t perVertexOffset = SIZE_MAX; // invalid value - BOOST_FOREACH( const InputChannel& channel, pPerIndexChannels) - { - numOffsets = std::max( numOffsets, channel.mOffset+1); - if( channel.mType == IT_Vertex) - perVertexOffset = channel.mOffset; - } - - // determine the expected number of indices - size_t expectedPointCount = 0; - switch( pPrimType) - { - case Prim_Polylist: - { - BOOST_FOREACH( size_t i, pVCount) - expectedPointCount += i; - break; - } - case Prim_Lines: - expectedPointCount = 2 * pNumPrimitives; - break; - case Prim_Triangles: - expectedPointCount = 3 * pNumPrimitives; - break; - default: - // other primitive types don't state the index count upfront... we need to guess - break; - } - - // and read all indices into a temporary array - std::vector indices; - if( expectedPointCount > 0) - indices.reserve( expectedPointCount * numOffsets); - - if (pNumPrimitives > 0) // It is possible to not contain any indicies - { - const char* content = GetTextContent(); - while( *content != 0) - { - // read a value. - // Hack: (thom) Some exporters put negative indices sometimes. We just try to carry on anyways. - int value = std::max( 0, strtol10( content, &content)); - indices.push_back( size_t( value)); - // skip whitespace after it - SkipSpacesAndLineEnd( &content); - } - } - - // complain if the index count doesn't fit - if( expectedPointCount > 0 && indices.size() != expectedPointCount * numOffsets) - ThrowException( "Expected different index count in

element."); - else if( expectedPointCount == 0 && (indices.size() % numOffsets) != 0) - ThrowException( "Expected different index count in

element."); - - // find the data for all sources - for( std::vector::iterator it = pMesh->mPerVertexData.begin(); it != pMesh->mPerVertexData.end(); ++it) - { - InputChannel& input = *it; - if( input.mResolved) - continue; - - // find accessor - input.mResolved = &ResolveLibraryReference( mAccessorLibrary, input.mAccessor); - // resolve accessor's data pointer as well, if neccessary - const Accessor* acc = input.mResolved; - if( !acc->mData) - acc->mData = &ResolveLibraryReference( mDataLibrary, acc->mSource); - } - // and the same for the per-index channels - for( std::vector::iterator it = pPerIndexChannels.begin(); it != pPerIndexChannels.end(); ++it) - { - InputChannel& input = *it; - if( input.mResolved) - continue; - - // ignore vertex pointer, it doesn't refer to an accessor - if( input.mType == IT_Vertex) - { - // warn if the vertex channel does not refer to the element in the same mesh - if( input.mAccessor != pMesh->mVertexID) - ThrowException( "Unsupported vertex referencing scheme."); - continue; - } - - // find accessor - input.mResolved = &ResolveLibraryReference( mAccessorLibrary, input.mAccessor); - // resolve accessor's data pointer as well, if neccessary - const Accessor* acc = input.mResolved; - if( !acc->mData) - acc->mData = &ResolveLibraryReference( mDataLibrary, acc->mSource); - } - - // For continued primitives, the given count does not come all in one

, but only one primitive per

- size_t numPrimitives = pNumPrimitives; - if( pPrimType == Prim_TriFans || pPrimType == Prim_Polygon) - numPrimitives = 1; - // For continued primitives, the given count is actually the number of

's inside the parent tag - if ( pPrimType == Prim_TriStrips){ - size_t numberOfVertices = indices.size() / numOffsets; - numPrimitives = numberOfVertices - 2; - } - - pMesh->mFaceSize.reserve( numPrimitives); - pMesh->mFacePosIndices.reserve( indices.size() / numOffsets); - - size_t polylistStartVertex = 0; - for (size_t currentPrimitive = 0; currentPrimitive < numPrimitives; currentPrimitive++) - { - // determine number of points for this primitive - size_t numPoints = 0; - switch( pPrimType) - { - case Prim_Lines: - numPoints = 2; - for (size_t currentVertex = 0; currentVertex < numPoints; currentVertex++) - CopyVertex(currentVertex, numOffsets, numPoints, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices); - break; - case Prim_Triangles: - numPoints = 3; - for (size_t currentVertex = 0; currentVertex < numPoints; currentVertex++) - CopyVertex(currentVertex, numOffsets, numPoints, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices); - break; - case Prim_TriStrips: - numPoints = 3; - ReadPrimTriStrips(numOffsets, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices); - break; - case Prim_Polylist: - numPoints = pVCount[currentPrimitive]; - for (size_t currentVertex = 0; currentVertex < numPoints; currentVertex++) - CopyVertex(polylistStartVertex + currentVertex, numOffsets, 1, perVertexOffset, pMesh, pPerIndexChannels, 0, indices); - polylistStartVertex += numPoints; - break; - case Prim_TriFans: - case Prim_Polygon: - numPoints = indices.size() / numOffsets; - for (size_t currentVertex = 0; currentVertex < numPoints; currentVertex++) - CopyVertex(currentVertex, numOffsets, numPoints, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices); - break; - default: - // LineStrip is not supported due to expected index unmangling - ThrowException( "Unsupported primitive type."); - break; - } - - // store the face size to later reconstruct the face from - pMesh->mFaceSize.push_back( numPoints); - } - - // if I ever get my hands on that guy who invented this steaming pile of indirection... - TestClosing( "p"); - return numPrimitives; -} - -void ColladaParser::CopyVertex(size_t currentVertex, size_t numOffsets, size_t numPoints, size_t perVertexOffset, Mesh* pMesh, std::vector& pPerIndexChannels, size_t currentPrimitive, const std::vector& indices){ - // calculate the base offset of the vertex whose attributes we ant to copy - size_t baseOffset = currentPrimitive * numOffsets * numPoints + currentVertex * numOffsets; - - // don't overrun the boundaries of the index list - size_t maxIndexRequested = baseOffset + numOffsets - 1; - ai_assert(maxIndexRequested < indices.size()); - - // extract per-vertex channels using the global per-vertex offset - for (std::vector::iterator it = pMesh->mPerVertexData.begin(); it != pMesh->mPerVertexData.end(); ++it) - ExtractDataObjectFromChannel(*it, indices[baseOffset + perVertexOffset], pMesh); - // and extract per-index channels using there specified offset - for (std::vector::iterator it = pPerIndexChannels.begin(); it != pPerIndexChannels.end(); ++it) - ExtractDataObjectFromChannel(*it, indices[baseOffset + it->mOffset], pMesh); - - // store the vertex-data index for later assignment of bone vertex weights - pMesh->mFacePosIndices.push_back(indices[baseOffset + perVertexOffset]); -} - -void ColladaParser::ReadPrimTriStrips(size_t numOffsets, size_t perVertexOffset, Mesh* pMesh, std::vector& pPerIndexChannels, size_t currentPrimitive, const std::vector& indices){ - if (currentPrimitive % 2 != 0){ - //odd tristrip triangles need their indices mangled, to preserve winding direction - CopyVertex(1, numOffsets, 1, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices); - CopyVertex(0, numOffsets, 1, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices); - CopyVertex(2, numOffsets, 1, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices); - } - else {//for non tristrips or even tristrip triangles - CopyVertex(0, numOffsets, 1, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices); - CopyVertex(1, numOffsets, 1, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices); - CopyVertex(2, numOffsets, 1, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices); - } -} - -// ------------------------------------------------------------------------------------------------ -// Extracts a single object from an input channel and stores it in the appropriate mesh data array -void ColladaParser::ExtractDataObjectFromChannel( const InputChannel& pInput, size_t pLocalIndex, Mesh* pMesh) -{ - // ignore vertex referrer - we handle them that separate - if( pInput.mType == IT_Vertex) - return; - - const Accessor& acc = *pInput.mResolved; - if( pLocalIndex >= acc.mCount) - ThrowException( boost::str( boost::format( "Invalid data index (%d/%d) in primitive specification") % pLocalIndex % acc.mCount)); - - // get a pointer to the start of the data object referred to by the accessor and the local index - const float* dataObject = &(acc.mData->mValues[0]) + acc.mOffset + pLocalIndex* acc.mStride; - - // assemble according to the accessors component sub-offset list. We don't care, yet, - // what kind of object exactly we're extracting here - float obj[4]; - for( size_t c = 0; c < 4; ++c) - obj[c] = dataObject[acc.mSubOffset[c]]; - - // now we reinterpret it according to the type we're reading here - switch( pInput.mType) - { - case IT_Position: // ignore all position streams except 0 - there can be only one position - if( pInput.mIndex == 0) - pMesh->mPositions.push_back( aiVector3D( obj[0], obj[1], obj[2])); - else - DefaultLogger::get()->error("Collada: just one vertex position stream supported"); - break; - case IT_Normal: - // pad to current vertex count if necessary - if( pMesh->mNormals.size() < pMesh->mPositions.size()-1) - pMesh->mNormals.insert( pMesh->mNormals.end(), pMesh->mPositions.size() - pMesh->mNormals.size() - 1, aiVector3D( 0, 1, 0)); - - // ignore all normal streams except 0 - there can be only one normal - if( pInput.mIndex == 0) - pMesh->mNormals.push_back( aiVector3D( obj[0], obj[1], obj[2])); - else - DefaultLogger::get()->error("Collada: just one vertex normal stream supported"); - break; - case IT_Tangent: - // pad to current vertex count if necessary - if( pMesh->mTangents.size() < pMesh->mPositions.size()-1) - pMesh->mTangents.insert( pMesh->mTangents.end(), pMesh->mPositions.size() - pMesh->mTangents.size() - 1, aiVector3D( 1, 0, 0)); - - // ignore all tangent streams except 0 - there can be only one tangent - if( pInput.mIndex == 0) - pMesh->mTangents.push_back( aiVector3D( obj[0], obj[1], obj[2])); - else - DefaultLogger::get()->error("Collada: just one vertex tangent stream supported"); - break; - case IT_Bitangent: - // pad to current vertex count if necessary - if( pMesh->mBitangents.size() < pMesh->mPositions.size()-1) - pMesh->mBitangents.insert( pMesh->mBitangents.end(), pMesh->mPositions.size() - pMesh->mBitangents.size() - 1, aiVector3D( 0, 0, 1)); - - // ignore all bitangent streams except 0 - there can be only one bitangent - if( pInput.mIndex == 0) - pMesh->mBitangents.push_back( aiVector3D( obj[0], obj[1], obj[2])); - else - DefaultLogger::get()->error("Collada: just one vertex bitangent stream supported"); - break; - case IT_Texcoord: - // up to 4 texture coord sets are fine, ignore the others - if( pInput.mIndex < AI_MAX_NUMBER_OF_TEXTURECOORDS) - { - // pad to current vertex count if necessary - if( pMesh->mTexCoords[pInput.mIndex].size() < pMesh->mPositions.size()-1) - pMesh->mTexCoords[pInput.mIndex].insert( pMesh->mTexCoords[pInput.mIndex].end(), - pMesh->mPositions.size() - pMesh->mTexCoords[pInput.mIndex].size() - 1, aiVector3D( 0, 0, 0)); - - pMesh->mTexCoords[pInput.mIndex].push_back( aiVector3D( obj[0], obj[1], obj[2])); - if (0 != acc.mSubOffset[2] || 0 != acc.mSubOffset[3]) /* hack ... consider cleaner solution */ - pMesh->mNumUVComponents[pInput.mIndex]=3; - } else - { - DefaultLogger::get()->error("Collada: too many texture coordinate sets. Skipping."); - } - break; - case IT_Color: - // up to 4 color sets are fine, ignore the others - if( pInput.mIndex < AI_MAX_NUMBER_OF_COLOR_SETS) - { - // pad to current vertex count if necessary - if( pMesh->mColors[pInput.mIndex].size() < pMesh->mPositions.size()-1) - pMesh->mColors[pInput.mIndex].insert( pMesh->mColors[pInput.mIndex].end(), - pMesh->mPositions.size() - pMesh->mColors[pInput.mIndex].size() - 1, aiColor4D( 0, 0, 0, 1)); - - aiColor4D result(0, 0, 0, 1); - for (size_t i = 0; i < pInput.mResolved->mSize; ++i) - { - result[i] = obj[pInput.mResolved->mSubOffset[i]]; - } - pMesh->mColors[pInput.mIndex].push_back(result); - } else - { - DefaultLogger::get()->error("Collada: too many vertex color sets. Skipping."); - } - - break; - default: - // IT_Invalid and IT_Vertex - ai_assert(false && "shouldn't ever get here"); - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads the library of node hierarchies and scene parts -void ColladaParser::ReadSceneLibrary() -{ - if( mReader->isEmptyElement()) - return; - - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - // a visual scene - generate root node under its ID and let ReadNode() do the recursive work - if( IsElement( "visual_scene")) - { - // read ID. Is optional according to the spec, but how on earth should a scene_instance refer to it then? - int indexID = GetAttribute( "id"); - const char* attrID = mReader->getAttributeValue( indexID); - - // read name if given. - int indexName = TestAttribute( "name"); - const char* attrName = "unnamed"; - if( indexName > -1) - attrName = mReader->getAttributeValue( indexName); - - // create a node and store it in the library under its ID - Node* node = new Node; - node->mID = attrID; - node->mName = attrName; - mNodeLibrary[node->mID] = node; - - ReadSceneNode( node); - } else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - { - if( strcmp( mReader->getNodeName(), "library_visual_scenes") == 0) - //ThrowException( "Expected end of \"library_visual_scenes\" element."); - - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads a scene node's contents including children and stores it in the given node -void ColladaParser::ReadSceneNode( Node* pNode) -{ - // quit immediately on elements - if( mReader->isEmptyElement()) - return; - - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - if( IsElement( "node")) - { - Node* child = new Node; - int attrID = TestAttribute( "id"); - if( attrID > -1) - child->mID = mReader->getAttributeValue( attrID); - int attrSID = TestAttribute( "sid"); - if( attrSID > -1) - child->mSID = mReader->getAttributeValue( attrSID); - - int attrName = TestAttribute( "name"); - if( attrName > -1) - child->mName = mReader->getAttributeValue( attrName); - - // TODO: (thom) support SIDs - // ai_assert( TestAttribute( "sid") == -1); - - if (pNode) - { - pNode->mChildren.push_back( child); - child->mParent = pNode; - } - else - { - // no parent node given, probably called from element. - // create new node in node library - mNodeLibrary[child->mID] = child; - } - - // read on recursively from there - ReadSceneNode( child); - continue; - } - // For any further stuff we need a valid node to work on - else if (!pNode) - continue; - - if( IsElement( "lookat")) - ReadNodeTransformation( pNode, TF_LOOKAT); - else if( IsElement( "matrix")) - ReadNodeTransformation( pNode, TF_MATRIX); - else if( IsElement( "rotate")) - ReadNodeTransformation( pNode, TF_ROTATE); - else if( IsElement( "scale")) - ReadNodeTransformation( pNode, TF_SCALE); - else if( IsElement( "skew")) - ReadNodeTransformation( pNode, TF_SKEW); - else if( IsElement( "translate")) - ReadNodeTransformation( pNode, TF_TRANSLATE); - else if( IsElement( "render") && pNode->mParent == NULL && 0 == pNode->mPrimaryCamera.length()) - { - // ... scene evaluation or, in other words, postprocessing pipeline, - // or, again in other words, a turing-complete description how to - // render a Collada scene. The only thing that is interesting for - // us is the primary camera. - int attrId = TestAttribute("camera_node"); - if (-1 != attrId) - { - const char* s = mReader->getAttributeValue(attrId); - if (s[0] != '#') - DefaultLogger::get()->error("Collada: Unresolved reference format of camera"); - else - pNode->mPrimaryCamera = s+1; - } - } - else if( IsElement( "instance_node")) - { - // find the node in the library - int attrID = TestAttribute( "url"); - if( attrID != -1) - { - const char* s = mReader->getAttributeValue(attrID); - if (s[0] != '#') - DefaultLogger::get()->error("Collada: Unresolved reference format of node"); - else - { - pNode->mNodeInstances.push_back(NodeInstance()); - pNode->mNodeInstances.back().mNode = s+1; - } - } - } - else if( IsElement( "instance_geometry") || IsElement( "instance_controller")) - { - // Reference to a mesh or controller, with possible material associations - ReadNodeGeometry( pNode); - } - else if( IsElement( "instance_light")) - { - // Reference to a light, name given in 'url' attribute - int attrID = TestAttribute("url"); - if (-1 == attrID) - DefaultLogger::get()->warn("Collada: Expected url attribute in element"); - else - { - const char* url = mReader->getAttributeValue( attrID); - if( url[0] != '#') - ThrowException( "Unknown reference format in element"); - - pNode->mLights.push_back(LightInstance()); - pNode->mLights.back().mLight = url+1; - } - } - else if( IsElement( "instance_camera")) - { - // Reference to a camera, name given in 'url' attribute - int attrID = TestAttribute("url"); - if (-1 == attrID) - DefaultLogger::get()->warn("Collada: Expected url attribute in element"); - else - { - const char* url = mReader->getAttributeValue( attrID); - if( url[0] != '#') - ThrowException( "Unknown reference format in element"); - - pNode->mCameras.push_back(CameraInstance()); - pNode->mCameras.back().mCamera = url+1; - } - } - else - { - // skip everything else for the moment - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads a node transformation entry of the given type and adds it to the given node's transformation list. -void ColladaParser::ReadNodeTransformation( Node* pNode, TransformType pType) -{ - if( mReader->isEmptyElement()) - return; - - std::string tagName = mReader->getNodeName(); - - Transform tf; - tf.mType = pType; - - // read SID - int indexSID = TestAttribute( "sid"); - if( indexSID >= 0) - tf.mID = mReader->getAttributeValue( indexSID); - - // how many parameters to read per transformation type - static const unsigned int sNumParameters[] = { 9, 4, 3, 3, 7, 16 }; - const char* content = GetTextContent(); - - // read as many parameters and store in the transformation - for( unsigned int a = 0; a < sNumParameters[pType]; a++) - { - // read a number - content = fast_atoreal_move( content, tf.f[a]); - // skip whitespace after it - SkipSpacesAndLineEnd( &content); - } - - // place the transformation at the queue of the node - pNode->mTransforms.push_back( tf); - - // and consume the closing tag - TestClosing( tagName.c_str()); -} - -// ------------------------------------------------------------------------------------------------ -// Processes bind_vertex_input and bind elements -void ColladaParser::ReadMaterialVertexInputBinding( Collada::SemanticMappingTable& tbl) -{ - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) { - if( IsElement( "bind_vertex_input")) - { - Collada::InputSemanticMapEntry vn; - - // effect semantic - int n = GetAttribute("semantic"); - std::string s = mReader->getAttributeValue(n); - - // input semantic - n = GetAttribute("input_semantic"); - vn.mType = GetTypeForSemantic( mReader->getAttributeValue(n) ); - - // index of input set - n = TestAttribute("input_set"); - if (-1 != n) - vn.mSet = mReader->getAttributeValueAsInt(n); - - tbl.mMap[s] = vn; - } - else if( IsElement( "bind")) { - DefaultLogger::get()->warn("Collada: Found unsupported element"); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { - if( strcmp( mReader->getNodeName(), "instance_material") == 0) - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads a mesh reference in a node and adds it to the node's mesh list -void ColladaParser::ReadNodeGeometry( Node* pNode) -{ - // referred mesh is given as an attribute of the element - int attrUrl = GetAttribute( "url"); - const char* url = mReader->getAttributeValue( attrUrl); - if( url[0] != '#') - ThrowException( "Unknown reference format"); - - Collada::MeshInstance instance; - instance.mMeshOrController = url+1; // skipping the leading # - - if( !mReader->isEmptyElement()) - { - // read material associations. Ignore additional elements inbetween - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - if( IsElement( "instance_material")) - { - // read ID of the geometry subgroup and the target material - int attrGroup = GetAttribute( "symbol"); - std::string group = mReader->getAttributeValue( attrGroup); - int attrMaterial = GetAttribute( "target"); - const char* urlMat = mReader->getAttributeValue( attrMaterial); - Collada::SemanticMappingTable s; - if( urlMat[0] == '#') - urlMat++; - - s.mMatName = urlMat; - - // resolve further material details + THIS UGLY AND NASTY semantic mapping stuff - if( !mReader->isEmptyElement()) - ReadMaterialVertexInputBinding(s); - - // store the association - instance.mMaterials[group] = s; - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - { - if( strcmp( mReader->getNodeName(), "instance_geometry") == 0 - || strcmp( mReader->getNodeName(), "instance_controller") == 0) - break; - } - } - } - - // store it - pNode->mMeshes.push_back( instance); -} - -// ------------------------------------------------------------------------------------------------ -// Reads the collada scene -void ColladaParser::ReadScene() -{ - if( mReader->isEmptyElement()) - return; - - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) { - if( IsElement( "instance_visual_scene")) - { - // should be the first and only occurence - if( mRootNode) - ThrowException( "Invalid scene containing multiple root nodes in element"); - - // read the url of the scene to instance. Should be of format "#some_name" - int urlIndex = GetAttribute( "url"); - const char* url = mReader->getAttributeValue( urlIndex); - if( url[0] != '#') - ThrowException( "Unknown reference format in element"); - - // find the referred scene, skip the leading # - NodeLibrary::const_iterator sit = mNodeLibrary.find( url+1); - if( sit == mNodeLibrary.end()) - ThrowException( "Unable to resolve visual_scene reference \"" + std::string(url) + "\" in element."); - mRootNode = sit->second; - } else { - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END){ - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Aborts the file reading with an exception -AI_WONT_RETURN void ColladaParser::ThrowException( const std::string& pError) const -{ - throw DeadlyImportError( boost::str( boost::format( "Collada: %s - %s") % mFileName % pError)); -} - -// ------------------------------------------------------------------------------------------------ -// Skips all data until the end node of the current element -void ColladaParser::SkipElement() -{ - // nothing to skip if it's an - if( mReader->isEmptyElement()) - return; - - // reroute - SkipElement( mReader->getNodeName()); -} - -// ------------------------------------------------------------------------------------------------ -// Skips all data until the end node of the given element -void ColladaParser::SkipElement( const char* pElement) -{ - // copy the current node's name because it'a pointer to the reader's internal buffer, - // which is going to change with the upcoming parsing - std::string element = pElement; - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - if( mReader->getNodeName() == element) - break; - } -} - -// ------------------------------------------------------------------------------------------------ -// Tests for an opening element of the given name, throws an exception if not found -void ColladaParser::TestOpening( const char* pName) -{ - // read element start - if( !mReader->read()) - ThrowException( boost::str( boost::format( "Unexpected end of file while beginning of <%s> element.") % pName)); - // whitespace in front is ok, just read again if found - if( mReader->getNodeType() == irr::io::EXN_TEXT) - if( !mReader->read()) - ThrowException( boost::str( boost::format( "Unexpected end of file while reading beginning of <%s> element.") % pName)); - - if( mReader->getNodeType() != irr::io::EXN_ELEMENT || strcmp( mReader->getNodeName(), pName) != 0) - ThrowException( boost::str( boost::format( "Expected start of <%s> element.") % pName)); -} - -// ------------------------------------------------------------------------------------------------ -// Tests for the closing tag of the given element, throws an exception if not found -void ColladaParser::TestClosing( const char* pName) -{ - // check if we're already on the closing tag and return right away - if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END && strcmp( mReader->getNodeName(), pName) == 0) - return; - - // if not, read some more - if( !mReader->read()) - ThrowException( boost::str( boost::format( "Unexpected end of file while reading end of <%s> element.") % pName)); - // whitespace in front is ok, just read again if found - if( mReader->getNodeType() == irr::io::EXN_TEXT) - if( !mReader->read()) - ThrowException( boost::str( boost::format( "Unexpected end of file while reading end of <%s> element.") % pName)); - - // but this has the be the closing tag, or we're lost - if( mReader->getNodeType() != irr::io::EXN_ELEMENT_END || strcmp( mReader->getNodeName(), pName) != 0) - ThrowException( boost::str( boost::format( "Expected end of <%s> element.") % pName)); -} - -// ------------------------------------------------------------------------------------------------ -// Returns the index of the named attribute or -1 if not found. Does not throw, therefore useful for optional attributes -int ColladaParser::GetAttribute( const char* pAttr) const -{ - int index = TestAttribute( pAttr); - if( index != -1) - return index; - - // attribute not found -> throw an exception - ThrowException( boost::str( boost::format( "Expected attribute \"%s\" for element <%s>.") % pAttr % mReader->getNodeName())); - return -1; -} - -// ------------------------------------------------------------------------------------------------ -// Tests the present element for the presence of one attribute, returns its index or throws an exception if not found -int ColladaParser::TestAttribute( const char* pAttr) const -{ - for( int a = 0; a < mReader->getAttributeCount(); a++) - if( strcmp( mReader->getAttributeName( a), pAttr) == 0) - return a; - - return -1; -} - -// ------------------------------------------------------------------------------------------------ -// Reads the text contents of an element, throws an exception if not given. Skips leading whitespace. -const char* ColladaParser::GetTextContent() -{ - const char* sz = TestTextContent(); - if(!sz) { - ThrowException( "Invalid contents in element \"n\"."); - } - return sz; -} - -// ------------------------------------------------------------------------------------------------ -// Reads the text contents of an element, returns NULL if not given. Skips leading whitespace. -const char* ColladaParser::TestTextContent() -{ - // present node should be the beginning of an element - if( mReader->getNodeType() != irr::io::EXN_ELEMENT || mReader->isEmptyElement()) - return NULL; - - // read contents of the element - if( !mReader->read() ) - return NULL; - if( mReader->getNodeType() != irr::io::EXN_TEXT) - return NULL; - - // skip leading whitespace - const char* text = mReader->getNodeData(); - SkipSpacesAndLineEnd( &text); - - return text; -} - -// ------------------------------------------------------------------------------------------------ -// Calculates the resulting transformation fromm all the given transform steps -aiMatrix4x4 ColladaParser::CalculateResultTransform( const std::vector& pTransforms) const -{ - aiMatrix4x4 res; - - for( std::vector::const_iterator it = pTransforms.begin(); it != pTransforms.end(); ++it) - { - const Transform& tf = *it; - switch( tf.mType) - { - case TF_LOOKAT: - { - aiVector3D pos( tf.f[0], tf.f[1], tf.f[2]); - aiVector3D dstPos( tf.f[3], tf.f[4], tf.f[5]); - aiVector3D up = aiVector3D( tf.f[6], tf.f[7], tf.f[8]).Normalize(); - aiVector3D dir = aiVector3D( dstPos - pos).Normalize(); - aiVector3D right = (dir ^ up).Normalize(); - - res *= aiMatrix4x4( - right.x, up.x, -dir.x, pos.x, - right.y, up.y, -dir.y, pos.y, - right.z, up.z, -dir.z, pos.z, - 0, 0, 0, 1); - break; - } - case TF_ROTATE: - { - aiMatrix4x4 rot; - float angle = tf.f[3] * float( AI_MATH_PI) / 180.0f; - aiVector3D axis( tf.f[0], tf.f[1], tf.f[2]); - aiMatrix4x4::Rotation( angle, axis, rot); - res *= rot; - break; - } - case TF_TRANSLATE: - { - aiMatrix4x4 trans; - aiMatrix4x4::Translation( aiVector3D( tf.f[0], tf.f[1], tf.f[2]), trans); - res *= trans; - break; - } - case TF_SCALE: - { - aiMatrix4x4 scale( tf.f[0], 0.0f, 0.0f, 0.0f, 0.0f, tf.f[1], 0.0f, 0.0f, 0.0f, 0.0f, tf.f[2], 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f); - res *= scale; - break; - } - case TF_SKEW: - // TODO: (thom) - ai_assert( false); - break; - case TF_MATRIX: - { - aiMatrix4x4 mat( tf.f[0], tf.f[1], tf.f[2], tf.f[3], tf.f[4], tf.f[5], tf.f[6], tf.f[7], - tf.f[8], tf.f[9], tf.f[10], tf.f[11], tf.f[12], tf.f[13], tf.f[14], tf.f[15]); - res *= mat; - break; - } - default: - ai_assert( false); - break; - } - } - - return res; -} - -// ------------------------------------------------------------------------------------------------ -// Determines the input data type for the given semantic string -Collada::InputType ColladaParser::GetTypeForSemantic( const std::string& pSemantic) -{ - if( pSemantic == "POSITION") - return IT_Position; - else if( pSemantic == "TEXCOORD") - return IT_Texcoord; - else if( pSemantic == "NORMAL") - return IT_Normal; - else if( pSemantic == "COLOR") - return IT_Color; - else if( pSemantic == "VERTEX") - return IT_Vertex; - else if( pSemantic == "BINORMAL" || pSemantic == "TEXBINORMAL") - return IT_Bitangent; - else if( pSemantic == "TANGENT" || pSemantic == "TEXTANGENT") - return IT_Tangent; - - DefaultLogger::get()->warn( boost::str( boost::format( "Unknown vertex input type \"%s\". Ignoring.") % pSemantic)); - return IT_Invalid; -} - -#endif // !! ASSIMP_BUILD_NO_DAE_IMPORTER diff --git a/code/ColladaParser upstream.h b/code/ColladaParser upstream.h deleted file mode 100644 index 6f99681be..000000000 --- a/code/ColladaParser upstream.h +++ /dev/null @@ -1,352 +0,0 @@ -/* - Open Asset Import Library (assimp) - ---------------------------------------------------------------------- - - Copyright (c) 2006-2015, assimp team - All rights reserved. - - Redistribution and use of this software in source and binary forms, - with or without modification, are permitted provided that the - following conditions are met: - - * Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - - * Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - ---------------------------------------------------------------------- - */ - -/** @file ColladaParser.h - * @brief Defines the parser helper class for the collada loader - */ - -#ifndef AI_COLLADAPARSER_H_INC -#define AI_COLLADAPARSER_H_INC - -#include "irrXMLWrapper.h" -#include "ColladaHelper.h" -#include "../include/assimp/ai_assert.h" -#include - -namespace Assimp -{ - - // ------------------------------------------------------------------------------------------ - /** Parser helper class for the Collada loader. - * - * Does all the XML reading and builds internal data structures from it, - * but leaves the resolving of all the references to the loader. - */ - class ColladaParser - { - friend class ColladaLoader; - - protected: - /** Constructor from XML file */ - ColladaParser( IOSystem* pIOHandler, const std::string& pFile); - - /** Destructor */ - ~ColladaParser(); - - /** Reads the contents of the file */ - void ReadContents(); - - /** Reads the structure of the file */ - void ReadStructure(); - - /** Reads asset informations such as coordinate system informations and legal blah */ - void ReadAssetInfo(); - - /** Reads the animation library */ - void ReadAnimationLibrary(); - - /** Reads an animation into the given parent structure */ - void ReadAnimation( Collada::Animation* pParent); - - /** Reads an animation sampler into the given anim channel */ - void ReadAnimationSampler( Collada::AnimationChannel& pChannel); - - /** Reads the skeleton controller library */ - void ReadControllerLibrary(); - - /** Reads a controller into the given mesh structure */ - void ReadController( Collada::Controller& pController); - - /** Reads the joint definitions for the given controller */ - void ReadControllerJoints( Collada::Controller& pController); - - /** Reads the joint weights for the given controller */ - void ReadControllerWeights( Collada::Controller& pController); - - /** Reads the image library contents */ - void ReadImageLibrary(); - - /** Reads an image entry into the given image */ - void ReadImage( Collada::Image& pImage); - - /** Reads the material library */ - void ReadMaterialLibrary(); - - /** Reads a material entry into the given material */ - void ReadMaterial( Collada::Material& pMaterial); - - /** Reads the camera library */ - void ReadCameraLibrary(); - - /** Reads a camera entry into the given camera */ - void ReadCamera( Collada::Camera& pCamera); - - /** Reads the light library */ - void ReadLightLibrary(); - - /** Reads a light entry into the given light */ - void ReadLight( Collada::Light& pLight); - - /** Reads the effect library */ - void ReadEffectLibrary(); - - /** Reads an effect entry into the given effect*/ - void ReadEffect( Collada::Effect& pEffect); - - /** Reads an COMMON effect profile */ - void ReadEffectProfileCommon( Collada::Effect& pEffect); - - /** Read sampler properties */ - void ReadSamplerProperties( Collada::Sampler& pSampler); - - /** Reads an effect entry containing a color or a texture defining that color */ - void ReadEffectColor( aiColor4D& pColor, Collada::Sampler& pSampler); - - /** Reads an effect entry containing a float */ - void ReadEffectFloat( float& pFloat); - - /** Reads an effect parameter specification of any kind */ - void ReadEffectParam( Collada::EffectParam& pParam); - - /** Reads the geometry library contents */ - void ReadGeometryLibrary(); - - /** Reads a geometry from the geometry library. */ - void ReadGeometry( Collada::Mesh* pMesh); - - /** Reads a mesh from the geometry library */ - void ReadMesh( Collada::Mesh* pMesh); - - /** Reads a source element - a combination of raw data and an accessor defining - * things that should not be redefinable. Yes, that's another rant. - */ - void ReadSource(); - - /** Reads a data array holding a number of elements, and stores it in the global library. - * Currently supported are array of floats and arrays of strings. - */ - void ReadDataArray(); - - /** Reads an accessor and stores it in the global library under the given ID - - * accessors use the ID of the parent element - */ - void ReadAccessor( const std::string& pID); - - /** Reads input declarations of per-vertex mesh data into the given mesh */ - void ReadVertexData( Collada::Mesh* pMesh); - - /** Reads input declarations of per-index mesh data into the given mesh */ - void ReadIndexData( Collada::Mesh* pMesh); - - /** Reads a single input channel element and stores it in the given array, if valid */ - void ReadInputChannel( std::vector& poChannels); - - /** Reads a

primitive index list and assembles the mesh data into the given mesh */ - size_t ReadPrimitives( Collada::Mesh* pMesh, std::vector& pPerIndexChannels, - size_t pNumPrimitives, const std::vector& pVCount, Collada::PrimitiveType pPrimType); - - /** Copies the data for a single primitive into the mesh, based on the InputChannels */ - void CopyVertex(size_t currentVertex, size_t numOffsets, size_t numPoints, size_t perVertexOffset, - Collada::Mesh* pMesh, std::vector& pPerIndexChannels, - size_t currentPrimitive, const std::vector& indices); - - /** Reads one triangle of a tristrip into the mesh */ - void ReadPrimTriStrips(size_t numOffsets, size_t perVertexOffset, Collada::Mesh* pMesh, - std::vector& pPerIndexChannels, size_t currentPrimitive, const std::vector& indices); - - /** Extracts a single object from an input channel and stores it in the appropriate mesh data array */ - void ExtractDataObjectFromChannel( const Collada::InputChannel& pInput, size_t pLocalIndex, Collada::Mesh* pMesh); - - /** Reads the library of node hierarchies and scene parts */ - void ReadSceneLibrary(); - - /** Reads a scene node's contents including children and stores it in the given node */ - void ReadSceneNode( Collada::Node* pNode); - - /** Reads a node transformation entry of the given type and adds it to the given node's transformation list. */ - void ReadNodeTransformation( Collada::Node* pNode, Collada::TransformType pType); - - /** Reads a mesh reference in a node and adds it to the node's mesh list */ - void ReadNodeGeometry( Collada::Node* pNode); - - /** Reads the collada scene */ - void ReadScene(); - - // Processes bind_vertex_input and bind elements - void ReadMaterialVertexInputBinding( Collada::SemanticMappingTable& tbl); - - protected: - /** Aborts the file reading with an exception */ - AI_WONT_RETURN void ThrowException( const std::string& pError) const AI_WONT_RETURN_SUFFIX; - - /** Skips all data until the end node of the current element */ - void SkipElement(); - - /** Skips all data until the end node of the given element */ - void SkipElement( const char* pElement); - - /** Compares the current xml element name to the given string and returns true if equal */ - bool IsElement( const char* pName) const; - - /** Tests for the opening tag of the given element, throws an exception if not found */ - void TestOpening( const char* pName); - - /** Tests for the closing tag of the given element, throws an exception if not found */ - void TestClosing( const char* pName); - - /** Checks the present element for the presence of the attribute, returns its index - or throws an exception if not found */ - int GetAttribute( const char* pAttr) const; - - /** Returns the index of the named attribute or -1 if not found. Does not throw, - therefore useful for optional attributes */ - int TestAttribute( const char* pAttr) const; - - /** Reads the text contents of an element, throws an exception if not given. - Skips leading whitespace. */ - const char* GetTextContent(); - - /** Reads the text contents of an element, returns NULL if not given. - Skips leading whitespace. */ - const char* TestTextContent(); - - /** Reads a single bool from current text content */ - bool ReadBoolFromTextContent(); - - /** Reads a single float from current text content */ - float ReadFloatFromTextContent(); - - /** Calculates the resulting transformation from all the given transform steps */ - aiMatrix4x4 CalculateResultTransform( const std::vector& pTransforms) const; - - /** Determines the input data type for the given semantic string */ - Collada::InputType GetTypeForSemantic( const std::string& pSemantic); - - /** Finds the item in the given library by its reference, throws if not found */ - template const Type& ResolveLibraryReference( - const std::map& pLibrary, const std::string& pURL) const; - - protected: - /** Filename, for a verbose error message */ - std::string mFileName; - - /** XML reader, member for everyday use */ - irr::io::IrrXMLReader* mReader; - - /** All data arrays found in the file by ID. Might be referred to by actually - everyone. Collada, you are a steaming pile of indirection. */ - typedef std::map DataLibrary; - DataLibrary mDataLibrary; - - /** Same for accessors which define how the data in a data array is accessed. */ - typedef std::map AccessorLibrary; - AccessorLibrary mAccessorLibrary; - - /** Mesh library: mesh by ID */ - typedef std::map MeshLibrary; - MeshLibrary mMeshLibrary; - - /** node library: root node of the hierarchy part by ID */ - typedef std::map NodeLibrary; - NodeLibrary mNodeLibrary; - - /** Image library: stores texture properties by ID */ - typedef std::map ImageLibrary; - ImageLibrary mImageLibrary; - - /** Effect library: surface attributes by ID */ - typedef std::map EffectLibrary; - EffectLibrary mEffectLibrary; - - /** Material library: surface material by ID */ - typedef std::map MaterialLibrary; - MaterialLibrary mMaterialLibrary; - - /** Light library: surface light by ID */ - typedef std::map LightLibrary; - LightLibrary mLightLibrary; - - /** Camera library: surface material by ID */ - typedef std::map CameraLibrary; - CameraLibrary mCameraLibrary; - - /** Controller library: joint controllers by ID */ - typedef std::map ControllerLibrary; - ControllerLibrary mControllerLibrary; - - /** Pointer to the root node. Don't delete, it just points to one of - the nodes in the node library. */ - Collada::Node* mRootNode; - - /** Root animation container */ - Collada::Animation mAnims; - - /** Size unit: how large compared to a meter */ - float mUnitSize; - - /** Which is the up vector */ - enum { UP_X, UP_Y, UP_Z } mUpDirection; - - /** Collada file format version */ - Collada::FormatVersion mFormat; - }; - - // ------------------------------------------------------------------------------------------------ - // Check for element match - inline bool ColladaParser::IsElement( const char* pName) const - { - ai_assert( mReader->getNodeType() == irr::io::EXN_ELEMENT); - return ::strcmp( mReader->getNodeName(), pName) == 0; - } - - // ------------------------------------------------------------------------------------------------ - // Finds the item in the given library by its reference, throws if not found - template - const Type& ColladaParser::ResolveLibraryReference( const std::map& pLibrary, const std::string& pURL) const - { - typename std::map::const_iterator it = pLibrary.find( pURL); - if( it == pLibrary.end()) - ThrowException( boost::str( boost::format( "Unable to resolve library reference \"%s\".") % pURL)); - return it->second; - } - -} // end of namespace Assimp - -#endif // AI_COLLADAPARSER_H_INC diff --git a/code/ColladaParser wil.cpp b/code/ColladaParser wil.cpp deleted file mode 100644 index daea1d70e..000000000 --- a/code/ColladaParser wil.cpp +++ /dev/null @@ -1,2933 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2012, assimp team - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -*/ - -/** @file ColladaParser.cpp - * @brief Implementation of the Collada parser helper - */ - -#include "AssimpPCH.h" -#ifndef ASSIMP_BUILD_NO_COLLADA_IMPORTER - -#include "ColladaParser.h" -#include "fast_atof.h" -#include "ParsingUtils.h" - -using namespace Assimp; -using namespace Assimp::Collada; - -// ------------------------------------------------------------------------------------------------ -// Constructor to be privately used by Importer -ColladaParser::ColladaParser( IOSystem* pIOHandler, const std::string& pFile) - : mFileName( pFile) -{ - mRootNode = NULL; - mUnitSize = 1.0f; - mUpDirection = UP_Y; - - // We assume the newest file format by default - mFormat = FV_1_5_n; - - // open the file - boost::scoped_ptr file( pIOHandler->Open( pFile)); - if( file.get() == NULL) - throw DeadlyImportError( "Failed to open file " + pFile + "."); - - // generate a XML reader for it - boost::scoped_ptr mIOWrapper( new CIrrXML_IOStreamReader( file.get())); - mReader = irr::io::createIrrXMLReader( mIOWrapper.get()); - if( !mReader) - ThrowException( "Collada: Unable to open file."); - - // start reading - ReadContents(); -} - -// ------------------------------------------------------------------------------------------------ -// Destructor, private as well -ColladaParser::~ColladaParser() -{ - delete mReader; - for( NodeLibrary::iterator it = mNodeLibrary.begin(); it != mNodeLibrary.end(); ++it) - delete it->second; - for( MeshLibrary::iterator it = mMeshLibrary.begin(); it != mMeshLibrary.end(); ++it) - delete it->second; -} - -// ------------------------------------------------------------------------------------------------ -// Read bool from text contents of current element -bool ColladaParser::ReadBoolFromTextContent() -{ - const char* cur = GetTextContent(); - return (!ASSIMP_strincmp(cur,"true",4) || '0' != *cur); -} - -// ------------------------------------------------------------------------------------------------ -// Read float from text contents of current element -float ColladaParser::ReadFloatFromTextContent() -{ - const char* cur = GetTextContent(); - return fast_atof(cur); -} - -// ------------------------------------------------------------------------------------------------ -// Reads the contents of the file -void ColladaParser::ReadContents() -{ - while( mReader->read()) - { - // handle the root element "COLLADA" - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - if( IsElement( "COLLADA")) - { - // check for 'version' attribute - const int attrib = TestAttribute("version"); - if (attrib != -1) { - const char* version = mReader->getAttributeValue(attrib); - - if (!::strncmp(version,"1.5",3)) { - mFormat = FV_1_5_n; - DefaultLogger::get()->debug("Collada schema version is 1.5.n"); - } - else if (!::strncmp(version,"1.4",3)) { - mFormat = FV_1_4_n; - DefaultLogger::get()->debug("Collada schema version is 1.4.n"); - } - else if (!::strncmp(version,"1.3",3)) { - mFormat = FV_1_3_n; - DefaultLogger::get()->debug("Collada schema version is 1.3.n"); - } - } - - ReadStructure(); - } else - { - DefaultLogger::get()->debug( boost::str( boost::format( "Ignoring global element <%s>.") % mReader->getNodeName())); - SkipElement(); - } - } else - { - // skip everything else silently - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads the structure of the file -void ColladaParser::ReadStructure() -{ - while( mReader->read()) - { - // beginning of elements - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - if( IsElement( "asset")) - ReadAssetInfo(); - else if( IsElement( "library_animations")) - ReadAnimationLibrary(); - else if( IsElement( "library_controllers")) - ReadControllerLibrary(); - else if( IsElement( "library_images")) - ReadImageLibrary(); - else if( IsElement( "library_materials")) - ReadMaterialLibrary(); - else if( IsElement( "library_effects")) - ReadEffectLibrary(); - else if( IsElement( "library_geometries")) - ReadGeometryLibrary(); - else if( IsElement( "library_visual_scenes")) - ReadSceneLibrary(); - else if( IsElement( "library_lights")) - ReadLightLibrary(); - else if( IsElement( "library_cameras")) - ReadCameraLibrary(); - else if( IsElement( "library_nodes")) - ReadSceneNode(NULL); /* some hacking to reuse this piece of code */ - else if( IsElement( "scene")) - ReadScene(); - else - SkipElement(); - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - { - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads asset informations such as coordinate system informations and legal blah -void ColladaParser::ReadAssetInfo() -{ - if( mReader->isEmptyElement()) - return; - - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - if( IsElement( "unit")) - { - // read unit data from the element's attributes - const int attrIndex = TestAttribute( "meter"); - if (attrIndex == -1) { - mUnitSize = 1.f; - } - else { - mUnitSize = mReader->getAttributeValueAsFloat( attrIndex); - } - - // consume the trailing stuff - if( !mReader->isEmptyElement()) - SkipElement(); - } - else if( IsElement( "up_axis")) - { - // read content, strip whitespace, compare - const char* content = GetTextContent(); - if( strncmp( content, "X_UP", 4) == 0) - mUpDirection = UP_X; - else if( strncmp( content, "Z_UP", 4) == 0) - mUpDirection = UP_Z; - else - mUpDirection = UP_Y; - - // check element end - TestClosing( "up_axis"); - } else - { - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - { - if( strcmp( mReader->getNodeName(), "asset") != 0) - ThrowException( "Expected end of element."); - - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads the animation library -void ColladaParser::ReadAnimationLibrary() -{ - if (mReader->isEmptyElement()) - return; - - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - if( IsElement( "animation")) - { - // delegate the reading. Depending on the inner elements it will be a container or a anim channel - ReadAnimation( &mAnims); - } else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - { - if( strcmp( mReader->getNodeName(), "library_animations") != 0) - ThrowException( "Expected end of element."); - - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads an animation into the given parent structure -void ColladaParser::ReadAnimation( Collada::Animation* pParent) -{ - if( mReader->isEmptyElement()) - return; - - // an element may be a container for grouping sub-elements or an animation channel - // this is the channel collection by ID, in case it has channels - typedef std::map ChannelMap; - ChannelMap channels; - // this is the anim container in case we're a container - Animation* anim = NULL; - - // optional name given as an attribute - std::string animName; - int indexName = TestAttribute( "name"); - int indexID = TestAttribute( "id"); - if( indexName >= 0) - animName = mReader->getAttributeValue( indexName); - else if( indexID >= 0) - animName = mReader->getAttributeValue( indexID); - else - animName = "animation"; - - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - // we have subanimations - if( IsElement( "animation")) - { - // create container from our element - if( !anim) - { - anim = new Animation; - anim->mName = animName; - pParent->mSubAnims.push_back( anim); - } - - // recurse into the subelement - ReadAnimation( anim); - } - else if( IsElement( "source")) - { - // possible animation data - we'll never know. Better store it - ReadSource(); - } - else if( IsElement( "sampler")) - { - // read the ID to assign the corresponding collada channel afterwards. - int indexID = GetAttribute( "id"); - std::string id = mReader->getAttributeValue( indexID); - ChannelMap::iterator newChannel = channels.insert( std::make_pair( id, AnimationChannel())).first; - - // have it read into a channel - ReadAnimationSampler( newChannel->second); - } - else if( IsElement( "channel")) - { - // the binding element whose whole purpose is to provide the target to animate - // Thanks, Collada! A directly posted information would have been too simple, I guess. - // Better add another indirection to that! Can't have enough of those. - int indexTarget = GetAttribute( "target"); - int indexSource = GetAttribute( "source"); - const char* sourceId = mReader->getAttributeValue( indexSource); - if( sourceId[0] == '#') - sourceId++; - ChannelMap::iterator cit = channels.find( sourceId); - if( cit != channels.end()) - cit->second.mTarget = mReader->getAttributeValue( indexTarget); - - if( !mReader->isEmptyElement()) - SkipElement(); - } - else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - { - if( strcmp( mReader->getNodeName(), "animation") != 0) - ThrowException( "Expected end of element."); - - break; - } - } - - // it turned out to have channels - add them - if( !channels.empty()) - { - // special filtering for stupid exporters packing each channel into a separate animation - if( channels.size() == 1) - { - pParent->mChannels.push_back( channels.begin()->second); - } else - { - // else create the animation, if not done yet, and store the channels - if( !anim) - { - anim = new Animation; - anim->mName = animName; - pParent->mSubAnims.push_back( anim); - } - for( ChannelMap::const_iterator it = channels.begin(); it != channels.end(); ++it) - anim->mChannels.push_back( it->second); - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads an animation sampler into the given anim channel -void ColladaParser::ReadAnimationSampler( Collada::AnimationChannel& pChannel) -{ - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - if( IsElement( "input")) - { - int indexSemantic = GetAttribute( "semantic"); - const char* semantic = mReader->getAttributeValue( indexSemantic); - int indexSource = GetAttribute( "source"); - const char* source = mReader->getAttributeValue( indexSource); - if( source[0] != '#') - ThrowException( "Unsupported URL format"); - source++; - - if( strcmp( semantic, "INPUT") == 0) - pChannel.mSourceTimes = source; - else if( strcmp( semantic, "OUTPUT") == 0) - pChannel.mSourceValues = source; - - if( !mReader->isEmptyElement()) - SkipElement(); - } - else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - { - if( strcmp( mReader->getNodeName(), "sampler") != 0) - ThrowException( "Expected end of element."); - - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads the skeleton controller library -void ColladaParser::ReadControllerLibrary() -{ - if (mReader->isEmptyElement()) - return; - - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - if( IsElement( "controller")) - { - // read ID. Ask the spec if it's neccessary or optional... you might be surprised. - int attrID = GetAttribute( "id"); - std::string id = mReader->getAttributeValue( attrID); - - // create an entry and store it in the library under its ID - mControllerLibrary[id] = Controller(); - - // read on from there - ReadController( mControllerLibrary[id]); - } else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - { - if( strcmp( mReader->getNodeName(), "library_controllers") != 0) - ThrowException( "Expected end of element."); - - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads a controller into the given mesh structure -void ColladaParser::ReadController( Collada::Controller& pController) -{ - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - // two types of controllers: "skin" and "morph". Only the first one is relevant, we skip the other - if( IsElement( "morph")) - { - // should skip everything inside, so there's no danger of catching elements inbetween - SkipElement(); - } - else if( IsElement( "skin")) - { - // read the mesh it refers to. According to the spec this could also be another - // controller, but I refuse to implement every single idea they've come up with - int sourceIndex = GetAttribute( "source"); - pController.mMeshId = mReader->getAttributeValue( sourceIndex) + 1; - } - else if( IsElement( "bind_shape_matrix")) - { - // content is 16 floats to define a matrix... it seems to be important for some models - const char* content = GetTextContent(); - - // read the 16 floats - for( unsigned int a = 0; a < 16; a++) - { - // read a number - content = fast_atoreal_move( content, pController.mBindShapeMatrix[a]); - // skip whitespace after it - SkipSpacesAndLineEnd( &content); - } - - TestClosing( "bind_shape_matrix"); - } - else if( IsElement( "source")) - { - // data array - we have specialists to handle this - ReadSource(); - } - else if( IsElement( "joints")) - { - ReadControllerJoints( pController); - } - else if( IsElement( "vertex_weights")) - { - ReadControllerWeights( pController); - } - else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - { - if( strcmp( mReader->getNodeName(), "controller") == 0) - break; - else if( strcmp( mReader->getNodeName(), "skin") != 0) - ThrowException( "Expected end of element."); - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads the joint definitions for the given controller -void ColladaParser::ReadControllerJoints( Collada::Controller& pController) -{ - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - // Input channels for joint data. Two possible semantics: "JOINT" and "INV_BIND_MATRIX" - if( IsElement( "input")) - { - int indexSemantic = GetAttribute( "semantic"); - const char* attrSemantic = mReader->getAttributeValue( indexSemantic); - int indexSource = GetAttribute( "source"); - const char* attrSource = mReader->getAttributeValue( indexSource); - - // local URLS always start with a '#'. We don't support global URLs - if( attrSource[0] != '#') - ThrowException( boost::str( boost::format( "Unsupported URL format in \"%s\" in source attribute of data element") % attrSource)); - attrSource++; - - // parse source URL to corresponding source - if( strcmp( attrSemantic, "JOINT") == 0) - pController.mJointNameSource = attrSource; - else if( strcmp( attrSemantic, "INV_BIND_MATRIX") == 0) - pController.mJointOffsetMatrixSource = attrSource; - else - ThrowException( boost::str( boost::format( "Unknown semantic \"%s\" in data element") % attrSemantic)); - - // skip inner data, if present - if( !mReader->isEmptyElement()) - SkipElement(); - } - else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - { - if( strcmp( mReader->getNodeName(), "joints") != 0) - ThrowException( "Expected end of element."); - - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads the joint weights for the given controller -void ColladaParser::ReadControllerWeights( Collada::Controller& pController) -{ - // read vertex count from attributes and resize the array accordingly - int indexCount = GetAttribute( "count"); - size_t vertexCount = (size_t) mReader->getAttributeValueAsInt( indexCount); - pController.mWeightCounts.resize( vertexCount); - - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - // Input channels for weight data. Two possible semantics: "JOINT" and "WEIGHT" - if( IsElement( "input") && vertexCount > 0 ) - { - InputChannel channel; - - int indexSemantic = GetAttribute( "semantic"); - const char* attrSemantic = mReader->getAttributeValue( indexSemantic); - int indexSource = GetAttribute( "source"); - const char* attrSource = mReader->getAttributeValue( indexSource); - int indexOffset = TestAttribute( "offset"); - if( indexOffset >= 0) - channel.mOffset = mReader->getAttributeValueAsInt( indexOffset); - - // local URLS always start with a '#'. We don't support global URLs - if( attrSource[0] != '#') - ThrowException( boost::str( boost::format( "Unsupported URL format in \"%s\" in source attribute of data element") % attrSource)); - channel.mAccessor = attrSource + 1; - - // parse source URL to corresponding source - if( strcmp( attrSemantic, "JOINT") == 0) - pController.mWeightInputJoints = channel; - else if( strcmp( attrSemantic, "WEIGHT") == 0) - pController.mWeightInputWeights = channel; - else - ThrowException( boost::str( boost::format( "Unknown semantic \"%s\" in data element") % attrSemantic)); - - // skip inner data, if present - if( !mReader->isEmptyElement()) - SkipElement(); - } - else if( IsElement( "vcount") && vertexCount > 0 ) - { - // read weight count per vertex - const char* text = GetTextContent(); - size_t numWeights = 0; - for( std::vector::iterator it = pController.mWeightCounts.begin(); it != pController.mWeightCounts.end(); ++it) - { - if( *text == 0) - ThrowException( "Out of data while reading "); - - *it = strtoul10( text, &text); - numWeights += *it; - SkipSpacesAndLineEnd( &text); - } - - TestClosing( "vcount"); - - // reserve weight count - pController.mWeights.resize( numWeights); - } - else if( IsElement( "v") && vertexCount > 0 ) - { - // read JointIndex - WeightIndex pairs - const char* text = GetTextContent(); - - for( std::vector< std::pair >::iterator it = pController.mWeights.begin(); it != pController.mWeights.end(); ++it) - { - if( *text == 0) - ThrowException( "Out of data while reading "); - it->first = strtoul10( text, &text); - SkipSpacesAndLineEnd( &text); - if( *text == 0) - ThrowException( "Out of data while reading "); - it->second = strtoul10( text, &text); - SkipSpacesAndLineEnd( &text); - } - - TestClosing( "v"); - } - else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - { - if( strcmp( mReader->getNodeName(), "vertex_weights") != 0) - ThrowException( "Expected end of element."); - - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads the image library contents -void ColladaParser::ReadImageLibrary() -{ - if( mReader->isEmptyElement()) - return; - - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) { - if( IsElement( "image")) - { - // read ID. Another entry which is "optional" by design but obligatory in reality - int attrID = GetAttribute( "id"); - std::string id = mReader->getAttributeValue( attrID); - - // create an entry and store it in the library under its ID - mImageLibrary[id] = Image(); - - // read on from there - ReadImage( mImageLibrary[id]); - } else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { - if( strcmp( mReader->getNodeName(), "library_images") != 0) - ThrowException( "Expected end of element."); - - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads an image entry into the given image -void ColladaParser::ReadImage( Collada::Image& pImage) -{ - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT){ - // Need to run different code paths here, depending on the Collada XSD version - if (IsElement("image")) { - SkipElement(); - } - else if( IsElement( "init_from")) - { - if (mFormat == FV_1_4_n) - { - // FIX: C4D exporter writes empty tags - if (!mReader->isEmptyElement()) { - // element content is filename - hopefully - const char* sz = TestTextContent(); - if (sz)pImage.mFileName = sz; - TestClosing( "init_from"); - } - if (!pImage.mFileName.length()) { - pImage.mFileName = "unknown_texture"; - } - } - else if (mFormat == FV_1_5_n) - { - // make sure we skip over mip and array initializations, which - // we don't support, but which could confuse the loader if - // they're not skipped. - int attrib = TestAttribute("array_index"); - if (attrib != -1 && mReader->getAttributeValueAsInt(attrib) > 0) { - DefaultLogger::get()->warn("Collada: Ignoring texture array index"); - continue; - } - - attrib = TestAttribute("mip_index"); - if (attrib != -1 && mReader->getAttributeValueAsInt(attrib) > 0) { - DefaultLogger::get()->warn("Collada: Ignoring MIP map layer"); - continue; - } - - // TODO: correctly jump over cube and volume maps? - } - } - else if (mFormat == FV_1_5_n) - { - if( IsElement( "ref")) - { - // element content is filename - hopefully - const char* sz = TestTextContent(); - if (sz)pImage.mFileName = sz; - TestClosing( "ref"); - } - else if( IsElement( "hex") && !pImage.mFileName.length()) - { - // embedded image. get format - const int attrib = TestAttribute("format"); - if (-1 == attrib) - DefaultLogger::get()->warn("Collada: Unknown image file format"); - else pImage.mEmbeddedFormat = mReader->getAttributeValue(attrib); - - const char* data = GetTextContent(); - - // hexadecimal-encoded binary octets. First of all, find the - // required buffer size to reserve enough storage. - const char* cur = data; - while (!IsSpaceOrNewLine(*cur)) cur++; - - const unsigned int size = (unsigned int)(cur-data) * 2; - pImage.mImageData.resize(size); - for (unsigned int i = 0; i < size;++i) - pImage.mImageData[i] = HexOctetToDecimal(data+(i<<1)); - - TestClosing( "hex"); - } - } - else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { - if( strcmp( mReader->getNodeName(), "image") == 0) - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads the material library -void ColladaParser::ReadMaterialLibrary() -{ - if( mReader->isEmptyElement()) - return; - - std::map names; - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - if( IsElement( "material")) - { - // read ID. By now you propably know my opinion about this "specification" - int attrID = GetAttribute( "id"); - std::string id = mReader->getAttributeValue( attrID); - - std::string name; - int attrName = TestAttribute("name"); - if (attrName >= 0) - name = mReader->getAttributeValue( attrName); - - // create an entry and store it in the library under its ID - mMaterialLibrary[id] = Material(); - - if( !name.empty()) - { - std::map::iterator it = names.find( name); - if( it != names.end()) - { - std::ostringstream strStream; - strStream << ++it->second; - name.append( " " + strStream.str()); - } - else - { - names[name] = 0; - } - - mMaterialLibrary[id].mName = name; - } - - ReadMaterial( mMaterialLibrary[id]); - } else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - { - if( strcmp( mReader->getNodeName(), "library_materials") != 0) - ThrowException( "Expected end of element."); - - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads the light library -void ColladaParser::ReadLightLibrary() -{ - if( mReader->isEmptyElement()) - return; - - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) { - if( IsElement( "light")) - { - // read ID. By now you propably know my opinion about this "specification" - int attrID = GetAttribute( "id"); - std::string id = mReader->getAttributeValue( attrID); - - // create an entry and store it in the library under its ID - ReadLight(mLightLibrary[id] = Light()); - - } else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { - if( strcmp( mReader->getNodeName(), "library_lights") != 0) - ThrowException( "Expected end of element."); - - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads the camera library -void ColladaParser::ReadCameraLibrary() -{ - if( mReader->isEmptyElement()) - return; - - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) { - if( IsElement( "camera")) - { - // read ID. By now you propably know my opinion about this "specification" - int attrID = GetAttribute( "id"); - std::string id = mReader->getAttributeValue( attrID); - - // create an entry and store it in the library under its ID - Camera& cam = mCameraLibrary[id]; - attrID = TestAttribute( "name"); - if (attrID != -1) - cam.mName = mReader->getAttributeValue( attrID); - - ReadCamera(cam); - - } else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { - if( strcmp( mReader->getNodeName(), "library_cameras") != 0) - ThrowException( "Expected end of element."); - - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads a material entry into the given material -void ColladaParser::ReadMaterial( Collada::Material& pMaterial) -{ - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) { - if (IsElement("material")) { - SkipElement(); - } - else if( IsElement( "instance_effect")) - { - // referred effect by URL - int attrUrl = GetAttribute( "url"); - const char* url = mReader->getAttributeValue( attrUrl); - if( url[0] != '#') - ThrowException( "Unknown reference format"); - - pMaterial.mEffect = url+1; - - SkipElement(); - } else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { - if( strcmp( mReader->getNodeName(), "material") != 0) - ThrowException( "Expected end of element."); - - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads a light entry into the given light -void ColladaParser::ReadLight( Collada::Light& pLight) -{ - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) { - if (IsElement("light")) { - SkipElement(); - } - else if (IsElement("spot")) { - pLight.mType = aiLightSource_SPOT; - } - else if (IsElement("ambient")) { - pLight.mType = aiLightSource_AMBIENT; - } - else if (IsElement("directional")) { - pLight.mType = aiLightSource_DIRECTIONAL; - } - else if (IsElement("point")) { - pLight.mType = aiLightSource_POINT; - } - else if (IsElement("color")) { - // text content contains 3 floats - const char* content = GetTextContent(); - - content = fast_atoreal_move( content, (float&)pLight.mColor.r); - SkipSpacesAndLineEnd( &content); - - content = fast_atoreal_move( content, (float&)pLight.mColor.g); - SkipSpacesAndLineEnd( &content); - - content = fast_atoreal_move( content, (float&)pLight.mColor.b); - SkipSpacesAndLineEnd( &content); - - TestClosing( "color"); - } - else if (IsElement("constant_attenuation")) { - pLight.mAttConstant = ReadFloatFromTextContent(); - TestClosing("constant_attenuation"); - } - else if (IsElement("linear_attenuation")) { - pLight.mAttLinear = ReadFloatFromTextContent(); - TestClosing("linear_attenuation"); - } - else if (IsElement("quadratic_attenuation")) { - pLight.mAttQuadratic = ReadFloatFromTextContent(); - TestClosing("quadratic_attenuation"); - } - else if (IsElement("falloff_angle")) { - pLight.mFalloffAngle = ReadFloatFromTextContent(); - TestClosing("falloff_angle"); - } - else if (IsElement("falloff_exponent")) { - pLight.mFalloffExponent = ReadFloatFromTextContent(); - TestClosing("falloff_exponent"); - } - // FCOLLADA extensions - // ------------------------------------------------------- - else if (IsElement("outer_cone")) { - pLight.mOuterAngle = ReadFloatFromTextContent(); - TestClosing("outer_cone"); - } - // ... and this one is even deprecated - else if (IsElement("penumbra_angle")) { - pLight.mPenumbraAngle = ReadFloatFromTextContent(); - TestClosing("penumbra_angle"); - } - else if (IsElement("intensity")) { - pLight.mIntensity = ReadFloatFromTextContent(); - TestClosing("intensity"); - } - else if (IsElement("falloff")) { - pLight.mOuterAngle = ReadFloatFromTextContent(); - TestClosing("falloff"); - } - else if (IsElement("hotspot_beam")) { - pLight.mFalloffAngle = ReadFloatFromTextContent(); - TestClosing("hotspot_beam"); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { - if( strcmp( mReader->getNodeName(), "light") == 0) - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads a camera entry into the given light -void ColladaParser::ReadCamera( Collada::Camera& pCamera) -{ - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) { - if (IsElement("camera")) { - SkipElement(); - } - else if (IsElement("orthographic")) { - pCamera.mOrtho = true; - } - else if (IsElement("xfov") || IsElement("xmag")) { - pCamera.mHorFov = ReadFloatFromTextContent(); - TestClosing((pCamera.mOrtho ? "xmag" : "xfov")); - } - else if (IsElement("yfov") || IsElement("ymag")) { - pCamera.mVerFov = ReadFloatFromTextContent(); - TestClosing((pCamera.mOrtho ? "ymag" : "yfov")); - } - else if (IsElement("aspect_ratio")) { - pCamera.mAspect = ReadFloatFromTextContent(); - TestClosing("aspect_ratio"); - } - else if (IsElement("znear")) { - pCamera.mZNear = ReadFloatFromTextContent(); - TestClosing("znear"); - } - else if (IsElement("zfar")) { - pCamera.mZFar = ReadFloatFromTextContent(); - TestClosing("zfar"); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { - if( strcmp( mReader->getNodeName(), "camera") == 0) - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads the effect library -void ColladaParser::ReadEffectLibrary() -{ - if (mReader->isEmptyElement()) { - return; - } - - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) { - if( IsElement( "effect")) - { - // read ID. Do I have to repeat my ranting about "optional" attributes? - int attrID = GetAttribute( "id"); - std::string id = mReader->getAttributeValue( attrID); - - // create an entry and store it in the library under its ID - mEffectLibrary[id] = Effect(); - // read on from there - ReadEffect( mEffectLibrary[id]); - } else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { - if( strcmp( mReader->getNodeName(), "library_effects") != 0) - ThrowException( "Expected end of element."); - - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads an effect entry into the given effect -void ColladaParser::ReadEffect( Collada::Effect& pEffect) -{ - // for the moment we don't support any other type of effect. - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - if( IsElement( "profile_COMMON")) - ReadEffectProfileCommon( pEffect); - else - SkipElement(); - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - { - if( strcmp( mReader->getNodeName(), "effect") != 0) - ThrowException( "Expected end of element."); - - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads an COMMON effect profile -void ColladaParser::ReadEffectProfileCommon( Collada::Effect& pEffect) -{ - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - if( IsElement( "newparam")) { - // save ID - int attrSID = GetAttribute( "sid"); - std::string sid = mReader->getAttributeValue( attrSID); - pEffect.mParams[sid] = EffectParam(); - ReadEffectParam( pEffect.mParams[sid]); - } - else if( IsElement( "technique") || IsElement( "extra")) - { - // just syntactic sugar - } - - else if( mFormat == FV_1_4_n && IsElement( "image")) - { - // read ID. Another entry which is "optional" by design but obligatory in reality - int attrID = GetAttribute( "id"); - std::string id = mReader->getAttributeValue( attrID); - - // create an entry and store it in the library under its ID - mImageLibrary[id] = Image(); - - // read on from there - ReadImage( mImageLibrary[id]); - } - - /* Shading modes */ - else if( IsElement( "phong")) - pEffect.mShadeType = Shade_Phong; - else if( IsElement( "constant")) - pEffect.mShadeType = Shade_Constant; - else if( IsElement( "lambert")) - pEffect.mShadeType = Shade_Lambert; - else if( IsElement( "blinn")) - pEffect.mShadeType = Shade_Blinn; - - /* Color + texture properties */ - else if( IsElement( "emission")) - ReadEffectColor( pEffect.mEmissive, pEffect.mTexEmissive); - else if( IsElement( "ambient")) - ReadEffectColor( pEffect.mAmbient, pEffect.mTexAmbient); - else if( IsElement( "diffuse")) - ReadEffectColor( pEffect.mDiffuse, pEffect.mTexDiffuse); - else if( IsElement( "specular")) - ReadEffectColor( pEffect.mSpecular, pEffect.mTexSpecular); - else if( IsElement( "reflective")) { - ReadEffectColor( pEffect.mReflective, pEffect.mTexReflective); - } - else if( IsElement( "transparent")) { - ReadEffectColor( pEffect.mTransparent,pEffect.mTexTransparent); - } - else if( IsElement( "shininess")) - ReadEffectFloat( pEffect.mShininess); - else if( IsElement( "reflectivity")) - ReadEffectFloat( pEffect.mReflectivity); - - /* Single scalar properties */ - else if( IsElement( "transparency")) - ReadEffectFloat( pEffect.mTransparency); - else if( IsElement( "index_of_refraction")) - ReadEffectFloat( pEffect.mRefractIndex); - - // GOOGLEEARTH/OKINO extensions - // ------------------------------------------------------- - else if( IsElement( "double_sided")) - pEffect.mDoubleSided = ReadBoolFromTextContent(); - - // FCOLLADA extensions - // ------------------------------------------------------- - else if( IsElement( "bump")) { - aiColor4D dummy; - ReadEffectColor( dummy,pEffect.mTexBump); - } - - // MAX3D extensions - // ------------------------------------------------------- - else if( IsElement( "wireframe")) { - pEffect.mWireframe = ReadBoolFromTextContent(); - TestClosing( "wireframe"); - } - else if( IsElement( "faceted")) { - pEffect.mFaceted = ReadBoolFromTextContent(); - TestClosing( "faceted"); - } - else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { - if( strcmp( mReader->getNodeName(), "profile_COMMON") == 0) - { - break; - } - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Read texture wrapping + UV transform settings from a profile==Maya chunk -void ColladaParser::ReadSamplerProperties( Sampler& out ) -{ - if (mReader->isEmptyElement()) { - return; - } - - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) { - - // MAYA extensions - // ------------------------------------------------------- - if( IsElement( "wrapU")) { - out.mWrapU = ReadBoolFromTextContent(); - TestClosing( "wrapU"); - } - else if( IsElement( "wrapV")) { - out.mWrapV = ReadBoolFromTextContent(); - TestClosing( "wrapV"); - } - else if( IsElement( "mirrorU")) { - out.mMirrorU = ReadBoolFromTextContent(); - TestClosing( "mirrorU"); - } - else if( IsElement( "mirrorV")) { - out.mMirrorV = ReadBoolFromTextContent(); - TestClosing( "mirrorV"); - } - else if( IsElement( "repeatU")) { - out.mTransform.mScaling.x = ReadFloatFromTextContent(); - TestClosing( "repeatU"); - } - else if( IsElement( "repeatV")) { - out.mTransform.mScaling.y = ReadFloatFromTextContent(); - TestClosing( "repeatV"); - } - else if( IsElement( "offsetU")) { - out.mTransform.mTranslation.x = ReadFloatFromTextContent(); - TestClosing( "offsetU"); - } - else if( IsElement( "offsetV")) { - out.mTransform.mTranslation.y = ReadFloatFromTextContent(); - TestClosing( "offsetV"); - } - else if( IsElement( "rotateUV")) { - out.mTransform.mRotation = ReadFloatFromTextContent(); - TestClosing( "rotateUV"); - } - else if( IsElement( "blend_mode")) { - - const char* sz = GetTextContent(); - // http://www.feelingsoftware.com/content/view/55/72/lang,en/ - // NONE, OVER, IN, OUT, ADD, SUBTRACT, MULTIPLY, DIFFERENCE, LIGHTEN, DARKEN, SATURATE, DESATURATE and ILLUMINATE - if (0 == ASSIMP_strincmp(sz,"ADD",3)) - out.mOp = aiTextureOp_Add; - - else if (0 == ASSIMP_strincmp(sz,"SUBTRACT",8)) - out.mOp = aiTextureOp_Subtract; - - else if (0 == ASSIMP_strincmp(sz,"MULTIPLY",8)) - out.mOp = aiTextureOp_Multiply; - - else { - DefaultLogger::get()->warn("Collada: Unsupported MAYA texture blend mode"); - } - TestClosing( "blend_mode"); - } - // OKINO extensions - // ------------------------------------------------------- - else if( IsElement( "weighting")) { - out.mWeighting = ReadFloatFromTextContent(); - TestClosing( "weighting"); - } - else if( IsElement( "mix_with_previous_layer")) { - out.mMixWithPrevious = ReadFloatFromTextContent(); - TestClosing( "mix_with_previous_layer"); - } - // MAX3D extensions - // ------------------------------------------------------- - else if( IsElement( "amount")) { - out.mWeighting = ReadFloatFromTextContent(); - TestClosing( "amount"); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { - if( strcmp( mReader->getNodeName(), "technique") == 0) - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads an effect entry containing a color or a texture defining that color -void ColladaParser::ReadEffectColor( aiColor4D& pColor, Sampler& pSampler) -{ - if (mReader->isEmptyElement()) - return; - - // Save current element name - const std::string curElem = mReader->getNodeName(); - - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) { - if( IsElement( "color")) - { - // text content contains 4 floats - const char* content = GetTextContent(); - - content = fast_atoreal_move( content, (float&)pColor.r); - SkipSpacesAndLineEnd( &content); - - content = fast_atoreal_move( content, (float&)pColor.g); - SkipSpacesAndLineEnd( &content); - - content = fast_atoreal_move( content, (float&)pColor.b); - SkipSpacesAndLineEnd( &content); - - content = fast_atoreal_move( content, (float&)pColor.a); - SkipSpacesAndLineEnd( &content); - TestClosing( "color"); - } - else if( IsElement( "texture")) - { - // get name of source textur/sampler - int attrTex = GetAttribute( "texture"); - pSampler.mName = mReader->getAttributeValue( attrTex); - - // get name of UV source channel. Specification demands it to be there, but some exporters - // don't write it. It will be the default UV channel in case it's missing. - attrTex = TestAttribute( "texcoord"); - if( attrTex >= 0 ) - pSampler.mUVChannel = mReader->getAttributeValue( attrTex); - //SkipElement(); - - // as we've read texture, the color needs to be 1,1,1,1 - pColor = aiColor4D(1.f, 1.f, 1.f, 1.f); - } - else if( IsElement( "technique")) - { - const int _profile = GetAttribute( "profile"); - const char* profile = mReader->getAttributeValue( _profile ); - - // Some extensions are quite useful ... ReadSamplerProperties processes - // several extensions in MAYA, OKINO and MAX3D profiles. - if (!::strcmp(profile,"MAYA") || !::strcmp(profile,"MAX3D") || !::strcmp(profile,"OKINO")) - { - // get more information on this sampler - ReadSamplerProperties(pSampler); - } - else SkipElement(); - } - else if( !IsElement( "extra")) - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END){ - if (mReader->getNodeName() == curElem) - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads an effect entry containing a float -void ColladaParser::ReadEffectFloat( float& pFloat) -{ - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT){ - if( IsElement( "float")) - { - // text content contains a single floats - const char* content = GetTextContent(); - content = fast_atoreal_move( content, pFloat); - SkipSpacesAndLineEnd( &content); - - TestClosing( "float"); - } else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END){ - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads an effect parameter specification of any kind -void ColladaParser::ReadEffectParam( Collada::EffectParam& pParam) -{ - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) { - if( IsElement( "surface")) - { - // image ID given inside tags - TestOpening( "init_from"); - const char* content = GetTextContent(); - pParam.mType = Param_Surface; - pParam.mReference = content; - TestClosing( "init_from"); - - // don't care for remaining stuff - SkipElement( "surface"); - } - else if( IsElement( "sampler2D")) - { - // surface ID is given inside tags - TestOpening( "source"); - const char* content = GetTextContent(); - pParam.mType = Param_Sampler; - pParam.mReference = content; - TestClosing( "source"); - - // don't care for remaining stuff - SkipElement( "sampler2D"); - } else - { - // ignore unknown element - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads the geometry library contents -void ColladaParser::ReadGeometryLibrary() -{ - if( mReader->isEmptyElement()) - return; - - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - if( IsElement( "geometry")) - { - // read ID. Another entry which is "optional" by design but obligatory in reality - int indexID = GetAttribute( "id"); - std::string id = mReader->getAttributeValue( indexID); - - // TODO: (thom) support SIDs - // ai_assert( TestAttribute( "sid") == -1); - - // create a mesh and store it in the library under its ID - Mesh* mesh = new Mesh; - mMeshLibrary[id] = mesh; - - // read the mesh name if it exists - const int nameIndex = TestAttribute("name"); - if(nameIndex != -1) - { - mesh->mName = mReader->getAttributeValue(nameIndex); - } - - // read on from there - ReadGeometry( mesh); - } else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - { - if( strcmp( mReader->getNodeName(), "library_geometries") != 0) - ThrowException( "Expected end of element."); - - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads a geometry from the geometry library. -void ColladaParser::ReadGeometry( Collada::Mesh* pMesh) -{ - if( mReader->isEmptyElement()) - return; - - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - if( IsElement( "mesh")) - { - // read on from there - ReadMesh( pMesh); - } else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - { - if( strcmp( mReader->getNodeName(), "geometry") != 0) - ThrowException( "Expected end of element."); - - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads a mesh from the geometry library -void ColladaParser::ReadMesh( Mesh* pMesh) -{ - if( mReader->isEmptyElement()) - return; - - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - if( IsElement( "source")) - { - // we have professionals dealing with this - ReadSource(); - } - else if( IsElement( "vertices")) - { - // read per-vertex mesh data - ReadVertexData( pMesh); - } - else if( IsElement( "triangles") || IsElement( "lines") || IsElement( "linestrips") - || IsElement( "polygons") || IsElement( "polylist") || IsElement( "trifans") || IsElement( "tristrips")) - { - // read per-index mesh data and faces setup - ReadIndexData( pMesh); - } else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - { - if( strcmp( mReader->getNodeName(), "technique_common") == 0) - { - // end of another meaningless element - read over it - } - else if( strcmp( mReader->getNodeName(), "mesh") == 0) - { - // end of element - we're done here - break; - } else - { - // everything else should be punished - ThrowException( "Expected end of element."); - } - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads a source element -void ColladaParser::ReadSource() -{ - int indexID = GetAttribute( "id"); - std::string sourceID = mReader->getAttributeValue( indexID); - - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - if( IsElement( "float_array") || IsElement( "IDREF_array") || IsElement( "Name_array")) - { - ReadDataArray(); - } - else if( IsElement( "technique_common")) - { - // I don't care for your profiles - } - else if( IsElement( "accessor")) - { - ReadAccessor( sourceID); - } else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - { - if( strcmp( mReader->getNodeName(), "source") == 0) - { - // end of - we're done - break; - } - else if( strcmp( mReader->getNodeName(), "technique_common") == 0) - { - // end of another meaningless element - read over it - } else - { - // everything else should be punished - ThrowException( "Expected end of element."); - } - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads a data array holding a number of floats, and stores it in the global library -void ColladaParser::ReadDataArray() -{ - std::string elmName = mReader->getNodeName(); - bool isStringArray = (elmName == "IDREF_array" || elmName == "Name_array"); - bool isEmptyElement = mReader->isEmptyElement(); - - // read attributes - int indexID = GetAttribute( "id"); - std::string id = mReader->getAttributeValue( indexID); - int indexCount = GetAttribute( "count"); - unsigned int count = (unsigned int) mReader->getAttributeValueAsInt( indexCount); - const char* content = TestTextContent(); - - // read values and store inside an array in the data library - mDataLibrary[id] = Data(); - Data& data = mDataLibrary[id]; - data.mIsStringArray = isStringArray; - - // some exporters write empty data arrays, but we need to conserve them anyways because others might reference them - if (content) - { - if( isStringArray) - { - data.mStrings.reserve( count); - std::string s; - - for( unsigned int a = 0; a < count; a++) - { - if( *content == 0) - ThrowException( "Expected more values while reading IDREF_array contents."); - - s.clear(); - while( !IsSpaceOrNewLine( *content)) - s += *content++; - data.mStrings.push_back( s); - - SkipSpacesAndLineEnd( &content); - } - } else - { - data.mValues.reserve( count); - - for( unsigned int a = 0; a < count; a++) - { - if( *content == 0) - ThrowException( "Expected more values while reading float_array contents."); - - float value; - // read a number - content = fast_atoreal_move( content, value); - data.mValues.push_back( value); - // skip whitespace after it - SkipSpacesAndLineEnd( &content); - } - } - } - - // test for closing tag - if( !isEmptyElement ) - TestClosing( elmName.c_str()); -} - -// ------------------------------------------------------------------------------------------------ -// Reads an accessor and stores it in the global library -void ColladaParser::ReadAccessor( const std::string& pID) -{ - // read accessor attributes - int attrSource = GetAttribute( "source"); - const char* source = mReader->getAttributeValue( attrSource); - if( source[0] != '#') - ThrowException( boost::str( boost::format( "Unknown reference format in url \"%s\" in source attribute of element.") % source)); - int attrCount = GetAttribute( "count"); - unsigned int count = (unsigned int) mReader->getAttributeValueAsInt( attrCount); - int attrOffset = TestAttribute( "offset"); - unsigned int offset = 0; - if( attrOffset > -1) - offset = (unsigned int) mReader->getAttributeValueAsInt( attrOffset); - int attrStride = TestAttribute( "stride"); - unsigned int stride = 1; - if( attrStride > -1) - stride = (unsigned int) mReader->getAttributeValueAsInt( attrStride); - - // store in the library under the given ID - mAccessorLibrary[pID] = Accessor(); - Accessor& acc = mAccessorLibrary[pID]; - acc.mCount = count; - acc.mOffset = offset; - acc.mStride = stride; - acc.mSource = source+1; // ignore the leading '#' - acc.mSize = 0; // gets incremented with every param - - // and read the components - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - if( IsElement( "param")) - { - // read data param - int attrName = TestAttribute( "name"); - std::string name; - if( attrName > -1) - { - name = mReader->getAttributeValue( attrName); - - // analyse for common type components and store it's sub-offset in the corresponding field - - /* Cartesian coordinates */ - if( name == "X") acc.mSubOffset[0] = acc.mParams.size(); - else if( name == "Y") acc.mSubOffset[1] = acc.mParams.size(); - else if( name == "Z") acc.mSubOffset[2] = acc.mParams.size(); - - /* RGBA colors */ - else if( name == "R") acc.mSubOffset[0] = acc.mParams.size(); - else if( name == "G") acc.mSubOffset[1] = acc.mParams.size(); - else if( name == "B") acc.mSubOffset[2] = acc.mParams.size(); - else if( name == "A") acc.mSubOffset[3] = acc.mParams.size(); - - /* UVWQ (STPQ) texture coordinates */ - else if( name == "S") acc.mSubOffset[0] = acc.mParams.size(); - else if( name == "T") acc.mSubOffset[1] = acc.mParams.size(); - else if( name == "P") acc.mSubOffset[2] = acc.mParams.size(); - // else if( name == "Q") acc.mSubOffset[3] = acc.mParams.size(); - /* 4D uv coordinates are not supported in Assimp */ - - /* Generic extra data, interpreted as UV data, too*/ - else if( name == "U") acc.mSubOffset[0] = acc.mParams.size(); - else if( name == "V") acc.mSubOffset[1] = acc.mParams.size(); - //else - // DefaultLogger::get()->warn( boost::str( boost::format( "Unknown accessor parameter \"%s\". Ignoring data channel.") % name)); - } - - // read data type - int attrType = TestAttribute( "type"); - if( attrType > -1) - { - // for the moment we only distinguish between a 4x4 matrix and anything else. - // TODO: (thom) I don't have a spec here at work. Check if there are other multi-value types - // which should be tested for here. - std::string type = mReader->getAttributeValue( attrType); - if( type == "float4x4") - acc.mSize += 16; - else - acc.mSize += 1; - } - - acc.mParams.push_back( name); - - // skip remaining stuff of this element, if any - SkipElement(); - } else - { - ThrowException( boost::str( boost::format( "Unexpected sub element <%s> in tag ") % mReader->getNodeName())); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - { - if( strcmp( mReader->getNodeName(), "accessor") != 0) - ThrowException( "Expected end of element."); - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads input declarations of per-vertex mesh data into the given mesh -void ColladaParser::ReadVertexData( Mesh* pMesh) -{ - // extract the ID of the element. Not that we care, but to catch strange referencing schemes we should warn about - int attrID= GetAttribute( "id"); - pMesh->mVertexID = mReader->getAttributeValue( attrID); - - // a number of elements - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - if( IsElement( "input")) - { - ReadInputChannel( pMesh->mPerVertexData); - } else - { - ThrowException( boost::str( boost::format( "Unexpected sub element <%s> in tag ") % mReader->getNodeName())); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - { - if( strcmp( mReader->getNodeName(), "vertices") != 0) - ThrowException( "Expected end of element."); - - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads input declarations of per-index mesh data into the given mesh -void ColladaParser::ReadIndexData( Mesh* pMesh) -{ - std::vector vcount; - std::vector perIndexData; - - // read primitive count from the attribute - int attrCount = GetAttribute( "count"); - size_t numPrimitives = (size_t) mReader->getAttributeValueAsInt( attrCount); - // some mesh types (e.g. tristrips) don't specify primitive count upfront, - // so we need to sum up the actual number of primitives while we read the

-tags - size_t actualPrimitives = 0; - - // material subgroup - int attrMaterial = TestAttribute( "material"); - SubMesh subgroup; - if( attrMaterial > -1) - subgroup.mMaterial = mReader->getAttributeValue( attrMaterial); - - // distinguish between polys and triangles - std::string elementName = mReader->getNodeName(); - PrimitiveType primType = Prim_Invalid; - if( IsElement( "lines")) - primType = Prim_Lines; - else if( IsElement( "linestrips")) - primType = Prim_LineStrip; - else if( IsElement( "polygons")) - primType = Prim_Polygon; - else if( IsElement( "polylist")) - primType = Prim_Polylist; - else if( IsElement( "triangles")) - primType = Prim_Triangles; - else if( IsElement( "trifans")) - primType = Prim_TriFans; - else if( IsElement( "tristrips")) - primType = Prim_TriStrips; - - ai_assert( primType != Prim_Invalid); - - // also a number of elements, but in addition a

primitive collection and propably index counts for all primitives - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - if( IsElement( "input")) - { - ReadInputChannel( perIndexData); - } - else if( IsElement( "vcount")) - { - if( !mReader->isEmptyElement()) - { - if (numPrimitives) // It is possible to define a mesh without any primitives - { - // case - specifies the number of indices for each polygon - const char* content = GetTextContent(); - vcount.reserve( numPrimitives); - for( unsigned int a = 0; a < numPrimitives; a++) - { - if( *content == 0) - ThrowException( "Expected more values while reading contents."); - // read a number - vcount.push_back( (size_t) strtoul10( content, &content)); - // skip whitespace after it - SkipSpacesAndLineEnd( &content); - } - } - - TestClosing( "vcount"); - } - } - else if( IsElement( "p")) - { - if( !mReader->isEmptyElement()) - { - // now here the actual fun starts - these are the indices to construct the mesh data from - actualPrimitives += ReadPrimitives(pMesh, perIndexData, numPrimitives, vcount, primType); - } - } - else if (IsElement("extra")) - { - SkipElement("extra"); - } else - { - ThrowException( boost::str( boost::format( "Unexpected sub element <%s> in tag <%s>") % mReader->getNodeName() % elementName)); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - { - if( mReader->getNodeName() != elementName) - ThrowException( boost::str( boost::format( "Expected end of <%s> element.") % elementName)); - - break; - } - } - - // small sanity check - if (primType != Prim_TriFans && primType != Prim_TriStrips && - primType != Prim_Lines) // this is ONLY to workaround a bug in SketchUp 15.3.331 where it writes the wrong 'count' when it writes out the 'lines'. - ai_assert(actualPrimitives == numPrimitives); - - // only when we're done reading all

tags (and thus know the final vertex count) can we commit the submesh - subgroup.mNumFaces = actualPrimitives; - pMesh->mSubMeshes.push_back(subgroup); -} - -// ------------------------------------------------------------------------------------------------ -// Reads a single input channel element and stores it in the given array, if valid -void ColladaParser::ReadInputChannel( std::vector& poChannels) -{ - InputChannel channel; - - // read semantic - int attrSemantic = GetAttribute( "semantic"); - std::string semantic = mReader->getAttributeValue( attrSemantic); - channel.mType = GetTypeForSemantic( semantic); - - // read source - int attrSource = GetAttribute( "source"); - const char* source = mReader->getAttributeValue( attrSource); - if( source[0] != '#') - ThrowException( boost::str( boost::format( "Unknown reference format in url \"%s\" in source attribute of element.") % source)); - channel.mAccessor = source+1; // skipping the leading #, hopefully the remaining text is the accessor ID only - - // read index offset, if per-index - int attrOffset = TestAttribute( "offset"); - if( attrOffset > -1) - channel.mOffset = mReader->getAttributeValueAsInt( attrOffset); - - // read set if texture coordinates - if(channel.mType == IT_Texcoord || channel.mType == IT_Color){ - int attrSet = TestAttribute("set"); - if(attrSet > -1){ - attrSet = mReader->getAttributeValueAsInt( attrSet); - if(attrSet < 0) - ThrowException( boost::str( boost::format( "Invalid index \"%i\" in set attribute of element") % (attrSet))); - - channel.mIndex = attrSet; - } - } - - // store, if valid type - if( channel.mType != IT_Invalid) - poChannels.push_back( channel); - - // skip remaining stuff of this element, if any - SkipElement(); -} - -// ------------------------------------------------------------------------------------------------ -// Reads a

primitive index list and assembles the mesh data into the given mesh -size_t ColladaParser::ReadPrimitives( Mesh* pMesh, std::vector& pPerIndexChannels, - size_t pNumPrimitives, const std::vector& pVCount, PrimitiveType pPrimType) -{ - // determine number of indices coming per vertex - // find the offset index for all per-vertex channels - size_t numOffsets = 1; - size_t perVertexOffset = SIZE_MAX; // invalid value - BOOST_FOREACH( const InputChannel& channel, pPerIndexChannels) - { - numOffsets = std::max( numOffsets, channel.mOffset+1); - if( channel.mType == IT_Vertex) - perVertexOffset = channel.mOffset; - } - - // determine the expected number of indices - size_t expectedPointCount = 0; - switch( pPrimType) - { - case Prim_Polylist: - { - BOOST_FOREACH( size_t i, pVCount) - expectedPointCount += i; - break; - } - case Prim_Lines: - expectedPointCount = 2 * pNumPrimitives; - break; - case Prim_Triangles: - expectedPointCount = 3 * pNumPrimitives; - break; - default: - // other primitive types don't state the index count upfront... we need to guess - break; - } - - // and read all indices into a temporary array - std::vector indices; - if( expectedPointCount > 0) - indices.reserve( expectedPointCount * numOffsets); - - if (pNumPrimitives > 0) // It is possible to not contain any indicies - { - const char* content = GetTextContent(); - while( *content != 0) - { - // read a value. - // Hack: (thom) Some exporters put negative indices sometimes. We just try to carry on anyways. - int value = std::max( 0, strtol10( content, &content)); - indices.push_back( size_t( value)); - // skip whitespace after it - SkipSpacesAndLineEnd( &content); - } - } - - // complain if the index count doesn't fit - if( expectedPointCount > 0 && indices.size() != expectedPointCount * numOffsets) { - if (pPrimType == Prim_Lines) { - // HACK: We just fix this number since SketchUp 15.3.331 writes the wrong 'count' for 'lines' - ReportWarning( "Expected different index count in

element, %d instead of %d.", indices.size(), expectedPointCount * numOffsets); - pNumPrimitives = (indices.size() / numOffsets) / 2; - } else - ThrowException( "Expected different index count in

element."); - - } else if( expectedPointCount == 0 && (indices.size() % numOffsets) != 0) - ThrowException( "Expected different index count in

element."); - - // find the data for all sources - for( std::vector::iterator it = pMesh->mPerVertexData.begin(); it != pMesh->mPerVertexData.end(); ++it) - { - InputChannel& input = *it; - if( input.mResolved) - continue; - - // find accessor - input.mResolved = &ResolveLibraryReference( mAccessorLibrary, input.mAccessor); - // resolve accessor's data pointer as well, if neccessary - const Accessor* acc = input.mResolved; - if( !acc->mData) - acc->mData = &ResolveLibraryReference( mDataLibrary, acc->mSource); - } - // and the same for the per-index channels - for( std::vector::iterator it = pPerIndexChannels.begin(); it != pPerIndexChannels.end(); ++it) - { - InputChannel& input = *it; - if( input.mResolved) - continue; - - // ignore vertex pointer, it doesn't refer to an accessor - if( input.mType == IT_Vertex) - { - // warn if the vertex channel does not refer to the element in the same mesh - if( input.mAccessor != pMesh->mVertexID) - ThrowException( "Unsupported vertex referencing scheme."); - continue; - } - - // find accessor - input.mResolved = &ResolveLibraryReference( mAccessorLibrary, input.mAccessor); - // resolve accessor's data pointer as well, if neccessary - const Accessor* acc = input.mResolved; - if( !acc->mData) - acc->mData = &ResolveLibraryReference( mDataLibrary, acc->mSource); - } - - // For continued primitives, the given count does not come all in one

, but only one primitive per

- size_t numPrimitives = pNumPrimitives; - if( pPrimType == Prim_TriFans || pPrimType == Prim_Polygon) - numPrimitives = 1; - // For continued primitives, the given count is actually the number of

's inside the parent tag - if ( pPrimType == Prim_TriStrips){ - size_t numberOfVertices = indices.size() / numOffsets; - numPrimitives = numberOfVertices - 2; - } - - pMesh->mFaceSize.reserve( numPrimitives); - pMesh->mFacePosIndices.reserve( indices.size() / numOffsets); - - size_t polylistStartVertex = 0; - for (size_t currentPrimitive = 0; currentPrimitive < numPrimitives; currentPrimitive++) - { - // determine number of points for this primitive - size_t numPoints = 0; - switch( pPrimType) - { - case Prim_Lines: - numPoints = 2; - for (size_t currentVertex = 0; currentVertex < numPoints; currentVertex++) - CopyVertex(currentVertex, numOffsets, numPoints, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices); - break; - case Prim_Triangles: - numPoints = 3; - for (size_t currentVertex = 0; currentVertex < numPoints; currentVertex++) - CopyVertex(currentVertex, numOffsets, numPoints, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices); - break; - case Prim_TriStrips: - numPoints = 3; - ReadPrimTriStrips(numOffsets, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices); - break; - case Prim_Polylist: - numPoints = pVCount[currentPrimitive]; - for (size_t currentVertex = 0; currentVertex < numPoints; currentVertex++) - CopyVertex(polylistStartVertex + currentVertex, numOffsets, 1, perVertexOffset, pMesh, pPerIndexChannels, 0, indices); - polylistStartVertex += numPoints; - break; - case Prim_TriFans: - case Prim_Polygon: - numPoints = indices.size() / numOffsets; - for (size_t currentVertex = 0; currentVertex < numPoints; currentVertex++) - CopyVertex(currentVertex, numOffsets, numPoints, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices); - break; - default: - // LineStrip is not supported due to expected index unmangling - ThrowException( "Unsupported primitive type."); - break; - } - - // store the face size to later reconstruct the face from - pMesh->mFaceSize.push_back( numPoints); - } - - // if I ever get my hands on that guy who invented this steaming pile of indirection... - TestClosing( "p"); - return numPrimitives; -} - -void ColladaParser::CopyVertex(size_t currentVertex, size_t numOffsets, size_t numPoints, size_t perVertexOffset, Mesh* pMesh, std::vector& pPerIndexChannels, size_t currentPrimitive, const std::vector& indices){ - // calculate the base offset of the vertex whose attributes we ant to copy - size_t baseOffset = currentPrimitive * numOffsets * numPoints + currentVertex * numOffsets; - - // don't overrun the boundaries of the index list - size_t maxIndexRequested = baseOffset + numOffsets - 1; - ai_assert(maxIndexRequested < indices.size()); - - // extract per-vertex channels using the global per-vertex offset - for (std::vector::iterator it = pMesh->mPerVertexData.begin(); it != pMesh->mPerVertexData.end(); ++it) - ExtractDataObjectFromChannel(*it, indices[baseOffset + perVertexOffset], pMesh); - // and extract per-index channels using there specified offset - for (std::vector::iterator it = pPerIndexChannels.begin(); it != pPerIndexChannels.end(); ++it) - ExtractDataObjectFromChannel(*it, indices[baseOffset + it->mOffset], pMesh); - - // store the vertex-data index for later assignment of bone vertex weights - pMesh->mFacePosIndices.push_back(indices[baseOffset + perVertexOffset]); -} - -void ColladaParser::ReadPrimTriStrips(size_t numOffsets, size_t perVertexOffset, Mesh* pMesh, std::vector& pPerIndexChannels, size_t currentPrimitive, const std::vector& indices){ - if (currentPrimitive % 2 != 0){ - //odd tristrip triangles need their indices mangled, to preserve winding direction - CopyVertex(1, numOffsets, 1, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices); - CopyVertex(0, numOffsets, 1, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices); - CopyVertex(2, numOffsets, 1, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices); - } - else {//for non tristrips or even tristrip triangles - CopyVertex(0, numOffsets, 1, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices); - CopyVertex(1, numOffsets, 1, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices); - CopyVertex(2, numOffsets, 1, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices); - } -} - -// ------------------------------------------------------------------------------------------------ -// Extracts a single object from an input channel and stores it in the appropriate mesh data array -void ColladaParser::ExtractDataObjectFromChannel( const InputChannel& pInput, size_t pLocalIndex, Mesh* pMesh) -{ - // ignore vertex referrer - we handle them that separate - if( pInput.mType == IT_Vertex) - return; - - const Accessor& acc = *pInput.mResolved; - if( pLocalIndex >= acc.mCount) - ThrowException( boost::str( boost::format( "Invalid data index (%d/%d) in primitive specification") % pLocalIndex % acc.mCount)); - - // get a pointer to the start of the data object referred to by the accessor and the local index - const float* dataObject = &(acc.mData->mValues[0]) + acc.mOffset + pLocalIndex* acc.mStride; - - // assemble according to the accessors component sub-offset list. We don't care, yet, - // what kind of object exactly we're extracting here - float obj[4]; - for( size_t c = 0; c < 4; ++c) - obj[c] = dataObject[acc.mSubOffset[c]]; - - // now we reinterpret it according to the type we're reading here - switch( pInput.mType) - { - case IT_Position: // ignore all position streams except 0 - there can be only one position - if( pInput.mIndex == 0) - pMesh->mPositions.push_back( aiVector3D( obj[0], obj[1], obj[2])); - else - DefaultLogger::get()->error("Collada: just one vertex position stream supported"); - break; - case IT_Normal: - // pad to current vertex count if necessary - if( pMesh->mNormals.size() < pMesh->mPositions.size()-1) - pMesh->mNormals.insert( pMesh->mNormals.end(), pMesh->mPositions.size() - pMesh->mNormals.size() - 1, aiVector3D( 0, 1, 0)); - - // ignore all normal streams except 0 - there can be only one normal - if( pInput.mIndex == 0) - pMesh->mNormals.push_back( aiVector3D( obj[0], obj[1], obj[2])); - else - DefaultLogger::get()->error("Collada: just one vertex normal stream supported"); - break; - case IT_Tangent: - // pad to current vertex count if necessary - if( pMesh->mTangents.size() < pMesh->mPositions.size()-1) - pMesh->mTangents.insert( pMesh->mTangents.end(), pMesh->mPositions.size() - pMesh->mTangents.size() - 1, aiVector3D( 1, 0, 0)); - - // ignore all tangent streams except 0 - there can be only one tangent - if( pInput.mIndex == 0) - pMesh->mTangents.push_back( aiVector3D( obj[0], obj[1], obj[2])); - else - DefaultLogger::get()->error("Collada: just one vertex tangent stream supported"); - break; - case IT_Bitangent: - // pad to current vertex count if necessary - if( pMesh->mBitangents.size() < pMesh->mPositions.size()-1) - pMesh->mBitangents.insert( pMesh->mBitangents.end(), pMesh->mPositions.size() - pMesh->mBitangents.size() - 1, aiVector3D( 0, 0, 1)); - - // ignore all bitangent streams except 0 - there can be only one bitangent - if( pInput.mIndex == 0) - pMesh->mBitangents.push_back( aiVector3D( obj[0], obj[1], obj[2])); - else - DefaultLogger::get()->error("Collada: just one vertex bitangent stream supported"); - break; - case IT_Texcoord: - // up to 4 texture coord sets are fine, ignore the others - if( pInput.mIndex < AI_MAX_NUMBER_OF_TEXTURECOORDS) - { - // pad to current vertex count if necessary - if( pMesh->mTexCoords[pInput.mIndex].size() < pMesh->mPositions.size()-1) - pMesh->mTexCoords[pInput.mIndex].insert( pMesh->mTexCoords[pInput.mIndex].end(), - pMesh->mPositions.size() - pMesh->mTexCoords[pInput.mIndex].size() - 1, aiVector3D( 0, 0, 0)); - - pMesh->mTexCoords[pInput.mIndex].push_back( aiVector3D( obj[0], obj[1], obj[2])); - if (0 != acc.mSubOffset[2] || 0 != acc.mSubOffset[3]) /* hack ... consider cleaner solution */ - pMesh->mNumUVComponents[pInput.mIndex]=3; - } else - { - DefaultLogger::get()->error("Collada: too many texture coordinate sets. Skipping."); - } - break; - case IT_Color: - // up to 4 color sets are fine, ignore the others - if( pInput.mIndex < AI_MAX_NUMBER_OF_COLOR_SETS) - { - // pad to current vertex count if necessary - if( pMesh->mColors[pInput.mIndex].size() < pMesh->mPositions.size()-1) - pMesh->mColors[pInput.mIndex].insert( pMesh->mColors[pInput.mIndex].end(), - pMesh->mPositions.size() - pMesh->mColors[pInput.mIndex].size() - 1, aiColor4D( 0, 0, 0, 1)); - - aiColor4D result(0, 0, 0, 1); - for (size_t i = 0; i < pInput.mResolved->mSize; ++i) - { - result[i] = obj[pInput.mResolved->mSubOffset[i]]; - } - pMesh->mColors[pInput.mIndex].push_back(result); - } else - { - DefaultLogger::get()->error("Collada: too many vertex color sets. Skipping."); - } - - break; - default: - // IT_Invalid and IT_Vertex - ai_assert(false && "shouldn't ever get here"); - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads the library of node hierarchies and scene parts -void ColladaParser::ReadSceneLibrary() -{ - if( mReader->isEmptyElement()) - return; - - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - // a visual scene - generate root node under its ID and let ReadNode() do the recursive work - if( IsElement( "visual_scene")) - { - // read ID. Is optional according to the spec, but how on earth should a scene_instance refer to it then? - int indexID = GetAttribute( "id"); - const char* attrID = mReader->getAttributeValue( indexID); - - // read name if given. - int indexName = TestAttribute( "name"); - const char* attrName = "unnamed"; - if( indexName > -1) - attrName = mReader->getAttributeValue( indexName); - - // create a node and store it in the library under its ID - Node* node = new Node; - node->mID = attrID; - node->mName = attrName; - mNodeLibrary[node->mID] = node; - - ReadSceneNode( node); - } else - { - // ignore the rest - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - { - if( strcmp( mReader->getNodeName(), "library_visual_scenes") == 0) - //ThrowException( "Expected end of \"library_visual_scenes\" element."); - - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads a scene node's contents including children and stores it in the given node -void ColladaParser::ReadSceneNode( Node* pNode) -{ - // quit immediately on elements - if( mReader->isEmptyElement()) - return; - - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - if( IsElement( "node")) - { - Node* child = new Node; - int attrID = TestAttribute( "id"); - if( attrID > -1) - child->mID = mReader->getAttributeValue( attrID); - int attrSID = TestAttribute( "sid"); - if( attrSID > -1) - child->mSID = mReader->getAttributeValue( attrSID); - - int attrName = TestAttribute( "name"); - if( attrName > -1) - child->mName = mReader->getAttributeValue( attrName); - - // TODO: (thom) support SIDs - // ai_assert( TestAttribute( "sid") == -1); - - if (pNode) - { - pNode->mChildren.push_back( child); - child->mParent = pNode; - } - else - { - // no parent node given, probably called from element. - // create new node in node library - mNodeLibrary[child->mID] = child; - } - - // read on recursively from there - ReadSceneNode( child); - continue; - } - // For any further stuff we need a valid node to work on - else if (!pNode) - continue; - - if( IsElement( "lookat")) - ReadNodeTransformation( pNode, TF_LOOKAT); - else if( IsElement( "matrix")) - ReadNodeTransformation( pNode, TF_MATRIX); - else if( IsElement( "rotate")) - ReadNodeTransformation( pNode, TF_ROTATE); - else if( IsElement( "scale")) - ReadNodeTransformation( pNode, TF_SCALE); - else if( IsElement( "skew")) - ReadNodeTransformation( pNode, TF_SKEW); - else if( IsElement( "translate")) - ReadNodeTransformation( pNode, TF_TRANSLATE); - else if( IsElement( "render") && pNode->mParent == NULL && 0 == pNode->mPrimaryCamera.length()) - { - // ... scene evaluation or, in other words, postprocessing pipeline, - // or, again in other words, a turing-complete description how to - // render a Collada scene. The only thing that is interesting for - // us is the primary camera. - int attrId = TestAttribute("camera_node"); - if (-1 != attrId) - { - const char* s = mReader->getAttributeValue(attrId); - if (s[0] != '#') - DefaultLogger::get()->error("Collada: Unresolved reference format of camera"); - else - pNode->mPrimaryCamera = s+1; - } - } - else if( IsElement( "instance_node")) - { - // find the node in the library - int attrID = TestAttribute( "url"); - if( attrID != -1) - { - const char* s = mReader->getAttributeValue(attrID); - if (s[0] != '#') - DefaultLogger::get()->error("Collada: Unresolved reference format of node"); - else - { - pNode->mNodeInstances.push_back(NodeInstance()); - pNode->mNodeInstances.back().mNode = s+1; - } - } - } - else if( IsElement( "instance_geometry") || IsElement( "instance_controller")) - { - // Reference to a mesh or controller, with possible material associations - ReadNodeGeometry( pNode); - } - else if( IsElement( "instance_light")) - { - // Reference to a light, name given in 'url' attribute - int attrID = TestAttribute("url"); - if (-1 == attrID) - DefaultLogger::get()->warn("Collada: Expected url attribute in element"); - else - { - const char* url = mReader->getAttributeValue( attrID); - if( url[0] != '#') - ThrowException( "Unknown reference format in element"); - - pNode->mLights.push_back(LightInstance()); - pNode->mLights.back().mLight = url+1; - } - } - else if( IsElement( "instance_camera")) - { - // Reference to a camera, name given in 'url' attribute - int attrID = TestAttribute("url"); - if (-1 == attrID) - DefaultLogger::get()->warn("Collada: Expected url attribute in element"); - else - { - const char* url = mReader->getAttributeValue( attrID); - if( url[0] != '#') - ThrowException( "Unknown reference format in element"); - - pNode->mCameras.push_back(CameraInstance()); - pNode->mCameras.back().mCamera = url+1; - } - } - else - { - // skip everything else for the moment - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads a node transformation entry of the given type and adds it to the given node's transformation list. -void ColladaParser::ReadNodeTransformation( Node* pNode, TransformType pType) -{ - if( mReader->isEmptyElement()) - return; - - std::string tagName = mReader->getNodeName(); - - Transform tf; - tf.mType = pType; - - // read SID - int indexSID = TestAttribute( "sid"); - if( indexSID >= 0) - tf.mID = mReader->getAttributeValue( indexSID); - - // how many parameters to read per transformation type - static const unsigned int sNumParameters[] = { 9, 4, 3, 3, 7, 16 }; - const char* content = GetTextContent(); - - // read as many parameters and store in the transformation - for( unsigned int a = 0; a < sNumParameters[pType]; a++) - { - // read a number - content = fast_atoreal_move( content, tf.f[a]); - // skip whitespace after it - SkipSpacesAndLineEnd( &content); - } - - // place the transformation at the queue of the node - pNode->mTransforms.push_back( tf); - - // and consume the closing tag - TestClosing( tagName.c_str()); -} - -// ------------------------------------------------------------------------------------------------ -// Processes bind_vertex_input and bind elements -void ColladaParser::ReadMaterialVertexInputBinding( Collada::SemanticMappingTable& tbl) -{ - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) { - if( IsElement( "bind_vertex_input")) - { - Collada::InputSemanticMapEntry vn; - - // effect semantic - int n = GetAttribute("semantic"); - std::string s = mReader->getAttributeValue(n); - - // input semantic - n = GetAttribute("input_semantic"); - vn.mType = GetTypeForSemantic( mReader->getAttributeValue(n) ); - - // index of input set - n = TestAttribute("input_set"); - if (-1 != n) - vn.mSet = mReader->getAttributeValueAsInt(n); - - tbl.mMap[s] = vn; - } - else if( IsElement( "bind")) { - DefaultLogger::get()->warn("Collada: Found unsupported element"); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { - if( strcmp( mReader->getNodeName(), "instance_material") == 0) - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Reads a mesh reference in a node and adds it to the node's mesh list -void ColladaParser::ReadNodeGeometry( Node* pNode) -{ - // referred mesh is given as an attribute of the element - int attrUrl = GetAttribute( "url"); - const char* url = mReader->getAttributeValue( attrUrl); - if( url[0] != '#') - ThrowException( "Unknown reference format"); - - Collada::MeshInstance instance; - instance.mMeshOrController = url+1; // skipping the leading # - - if( !mReader->isEmptyElement()) - { - // read material associations. Ignore additional elements inbetween - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) - { - if( IsElement( "instance_material")) - { - // read ID of the geometry subgroup and the target material - int attrGroup = GetAttribute( "symbol"); - std::string group = mReader->getAttributeValue( attrGroup); - int attrMaterial = GetAttribute( "target"); - const char* urlMat = mReader->getAttributeValue( attrMaterial); - Collada::SemanticMappingTable s; - if( urlMat[0] == '#') - urlMat++; - - s.mMatName = urlMat; - - // resolve further material details + THIS UGLY AND NASTY semantic mapping stuff - if( !mReader->isEmptyElement()) - ReadMaterialVertexInputBinding(s); - - // store the association - instance.mMaterials[group] = s; - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - { - if( strcmp( mReader->getNodeName(), "instance_geometry") == 0 - || strcmp( mReader->getNodeName(), "instance_controller") == 0) - break; - } - } - } - - // store it - pNode->mMeshes.push_back( instance); -} - -// ------------------------------------------------------------------------------------------------ -// Reads the collada scene -void ColladaParser::ReadScene() -{ - if( mReader->isEmptyElement()) - return; - - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) { - if( IsElement( "instance_visual_scene")) - { - // should be the first and only occurence - if( mRootNode) - ThrowException( "Invalid scene containing multiple root nodes in element"); - - // read the url of the scene to instance. Should be of format "#some_name" - int urlIndex = GetAttribute( "url"); - const char* url = mReader->getAttributeValue( urlIndex); - if( url[0] != '#') - ThrowException( "Unknown reference format in element"); - - // find the referred scene, skip the leading # - NodeLibrary::const_iterator sit = mNodeLibrary.find( url+1); - if( sit == mNodeLibrary.end()) - ThrowException( "Unable to resolve visual_scene reference \"" + std::string(url) + "\" in element."); - mRootNode = sit->second; - } else { - SkipElement(); - } - } - else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END){ - break; - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Aborts the file reading with an exception -AI_WONT_RETURN void ColladaParser::ThrowException( const std::string& pError) const -{ - throw DeadlyImportError( boost::str( boost::format( "Collada: %s - %s") % mFileName % pError)); -} - -void ColladaParser::ReportWarning(const char* msg,...) -{ - ai_assert(NULL != msg); - - va_list args; - va_start(args,msg); - - char szBuffer[3000]; - const int iLen = vsprintf(szBuffer,msg,args); - ai_assert(iLen > 0); - - va_end(args); - DefaultLogger::get()->warn("Validation warning: " + std::string(szBuffer,iLen)); -} - -// ------------------------------------------------------------------------------------------------ -// Skips all data until the end node of the current element -void ColladaParser::SkipElement() -{ - // nothing to skip if it's an - if( mReader->isEmptyElement()) - return; - - // reroute - SkipElement( mReader->getNodeName()); -} - -// ------------------------------------------------------------------------------------------------ -// Skips all data until the end node of the given element -void ColladaParser::SkipElement( const char* pElement) -{ - // copy the current node's name because it'a pointer to the reader's internal buffer, - // which is going to change with the upcoming parsing - std::string element = pElement; - while( mReader->read()) - { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) - if( mReader->getNodeName() == element) - break; - } -} - -// ------------------------------------------------------------------------------------------------ -// Tests for an opening element of the given name, throws an exception if not found -void ColladaParser::TestOpening( const char* pName) -{ - // read element start - if( !mReader->read()) - ThrowException( boost::str( boost::format( "Unexpected end of file while beginning of <%s> element.") % pName)); - // whitespace in front is ok, just read again if found - if( mReader->getNodeType() == irr::io::EXN_TEXT) - if( !mReader->read()) - ThrowException( boost::str( boost::format( "Unexpected end of file while reading beginning of <%s> element.") % pName)); - - if( mReader->getNodeType() != irr::io::EXN_ELEMENT || strcmp( mReader->getNodeName(), pName) != 0) - ThrowException( boost::str( boost::format( "Expected start of <%s> element.") % pName)); -} - -// ------------------------------------------------------------------------------------------------ -// Tests for the closing tag of the given element, throws an exception if not found -void ColladaParser::TestClosing( const char* pName) -{ - // check if we're already on the closing tag and return right away - if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END && strcmp( mReader->getNodeName(), pName) == 0) - return; - - // if not, read some more - if( !mReader->read()) - ThrowException( boost::str( boost::format( "Unexpected end of file while reading end of <%s> element.") % pName)); - // whitespace in front is ok, just read again if found - if( mReader->getNodeType() == irr::io::EXN_TEXT) - if( !mReader->read()) - ThrowException( boost::str( boost::format( "Unexpected end of file while reading end of <%s> element.") % pName)); - - // but this has the be the closing tag, or we're lost - if( mReader->getNodeType() != irr::io::EXN_ELEMENT_END || strcmp( mReader->getNodeName(), pName) != 0) - ThrowException( boost::str( boost::format( "Expected end of <%s> element.") % pName)); -} - -// ------------------------------------------------------------------------------------------------ -// Returns the index of the named attribute or -1 if not found. Does not throw, therefore useful for optional attributes -int ColladaParser::GetAttribute( const char* pAttr) const -{ - int index = TestAttribute( pAttr); - if( index != -1) - return index; - - // attribute not found -> throw an exception - ThrowException( boost::str( boost::format( "Expected attribute \"%s\" for element <%s>.") % pAttr % mReader->getNodeName())); - return -1; -} - -// ------------------------------------------------------------------------------------------------ -// Tests the present element for the presence of one attribute, returns its index or throws an exception if not found -int ColladaParser::TestAttribute( const char* pAttr) const -{ - for( int a = 0; a < mReader->getAttributeCount(); a++) - if( strcmp( mReader->getAttributeName( a), pAttr) == 0) - return a; - - return -1; -} - -// ------------------------------------------------------------------------------------------------ -// Reads the text contents of an element, throws an exception if not given. Skips leading whitespace. -const char* ColladaParser::GetTextContent() -{ - const char* sz = TestTextContent(); - if(!sz) { - ThrowException( "Invalid contents in element \"n\"."); - } - return sz; -} - -// ------------------------------------------------------------------------------------------------ -// Reads the text contents of an element, returns NULL if not given. Skips leading whitespace. -const char* ColladaParser::TestTextContent() -{ - // present node should be the beginning of an element - if( mReader->getNodeType() != irr::io::EXN_ELEMENT || mReader->isEmptyElement()) - return NULL; - - // read contents of the element - if( !mReader->read() ) - return NULL; - if( mReader->getNodeType() != irr::io::EXN_TEXT) - return NULL; - - // skip leading whitespace - const char* text = mReader->getNodeData(); - SkipSpacesAndLineEnd( &text); - - return text; -} - -// ------------------------------------------------------------------------------------------------ -// Calculates the resulting transformation fromm all the given transform steps -aiMatrix4x4 ColladaParser::CalculateResultTransform( const std::vector& pTransforms) const -{ - aiMatrix4x4 res; - - for( std::vector::const_iterator it = pTransforms.begin(); it != pTransforms.end(); ++it) - { - const Transform& tf = *it; - switch( tf.mType) - { - case TF_LOOKAT: - { - aiVector3D pos( tf.f[0], tf.f[1], tf.f[2]); - aiVector3D dstPos( tf.f[3], tf.f[4], tf.f[5]); - aiVector3D up = aiVector3D( tf.f[6], tf.f[7], tf.f[8]).Normalize(); - aiVector3D dir = aiVector3D( dstPos - pos).Normalize(); - aiVector3D right = (dir ^ up).Normalize(); - - res *= aiMatrix4x4( - right.x, up.x, -dir.x, pos.x, - right.y, up.y, -dir.y, pos.y, - right.z, up.z, -dir.z, pos.z, - 0, 0, 0, 1); - break; - } - case TF_ROTATE: - { - aiMatrix4x4 rot; - float angle = tf.f[3] * float( AI_MATH_PI) / 180.0f; - aiVector3D axis( tf.f[0], tf.f[1], tf.f[2]); - aiMatrix4x4::Rotation( angle, axis, rot); - res *= rot; - break; - } - case TF_TRANSLATE: - { - aiMatrix4x4 trans; - aiMatrix4x4::Translation( aiVector3D( tf.f[0], tf.f[1], tf.f[2]), trans); - res *= trans; - break; - } - case TF_SCALE: - { - aiMatrix4x4 scale( tf.f[0], 0.0f, 0.0f, 0.0f, 0.0f, tf.f[1], 0.0f, 0.0f, 0.0f, 0.0f, tf.f[2], 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f); - res *= scale; - break; - } - case TF_SKEW: - // TODO: (thom) - ai_assert( false); - break; - case TF_MATRIX: - { - aiMatrix4x4 mat( tf.f[0], tf.f[1], tf.f[2], tf.f[3], tf.f[4], tf.f[5], tf.f[6], tf.f[7], - tf.f[8], tf.f[9], tf.f[10], tf.f[11], tf.f[12], tf.f[13], tf.f[14], tf.f[15]); - res *= mat; - break; - } - default: - ai_assert( false); - break; - } - } - - return res; -} - -// ------------------------------------------------------------------------------------------------ -// Determines the input data type for the given semantic string -Collada::InputType ColladaParser::GetTypeForSemantic( const std::string& pSemantic) -{ - if( pSemantic == "POSITION") - return IT_Position; - else if( pSemantic == "TEXCOORD") - return IT_Texcoord; - else if( pSemantic == "NORMAL") - return IT_Normal; - else if( pSemantic == "COLOR") - return IT_Color; - else if( pSemantic == "VERTEX") - return IT_Vertex; - else if( pSemantic == "BINORMAL" || pSemantic == "TEXBINORMAL") - return IT_Bitangent; - else if( pSemantic == "TANGENT" || pSemantic == "TEXTANGENT") - return IT_Tangent; - - DefaultLogger::get()->warn( boost::str( boost::format( "Unknown vertex input type \"%s\". Ignoring.") % pSemantic)); - return IT_Invalid; -} - -#endif // !! ASSIMP_BUILD_NO_DAE_IMPORTER From 9708a4db934d21fb2b5695c4db4770d29d65c4b8 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sun, 30 Aug 2015 13:48:00 +0200 Subject: [PATCH 49/51] Subdivision: fix compiler warning from debug check. --- code/Subdivision.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/code/Subdivision.cpp b/code/Subdivision.cpp index 2c1c2ea7d..1443f46eb 100644 --- a/code/Subdivision.cpp +++ b/code/Subdivision.cpp @@ -399,10 +399,14 @@ void CatmullClarkSubdivider::InternSubdivide ( bool haveit = false; for (unsigned int i = 0; i < f.mNumIndices; ++i) { if (maptbl[FLATTEN_VERTEX_IDX(n,f.mIndices[i])]==(unsigned int)t) { - haveit = true; break; + haveit = true; + break; } } ai_assert(haveit); + if (!haveit) { + DefaultLogger::get()->debug("Catmull-Clark Subdivider: Index not used"); + } break; } } From e4510c26ba2a58fbd3a97ce8109d972d8b8c1eca Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sun, 30 Aug 2015 15:21:53 +0200 Subject: [PATCH 50/51] Obj-Importer: fix https://github.com/assimp/assimp/issues/641 --- code/ObjFileImporter.cpp | 24 ++++++---- code/ObjFileParser.cpp | 60 ++++++++++++----------- code/ObjFileParser.h | 8 ++-- include/assimp/IOSystem.hpp | 51 +++++++++++++++++++- test/CMakeLists.txt | 1 + test/unit/utIOSystem.cpp | 94 +++++++++++++++++++++++++++++++++++++ 6 files changed, 197 insertions(+), 41 deletions(-) create mode 100644 test/unit/utIOSystem.cpp diff --git a/code/ObjFileImporter.cpp b/code/ObjFileImporter.cpp index e4046b53b..7bf6154df 100644 --- a/code/ObjFileImporter.cpp +++ b/code/ObjFileImporter.cpp @@ -133,15 +133,16 @@ void ObjFileImporter::InternReadFile( const std::string& pFile, aiScene* pScene, TextFileToBuffer(file.get(),m_Buffer); // Get the model name - std::string strModelName; + std::string modelName, folderName; std::string::size_type pos = pFile.find_last_of( "\\/" ); - if ( pos != std::string::npos ) - { - strModelName = pFile.substr(pos+1, pFile.size() - pos - 1); - } - else - { - strModelName = pFile; + if ( pos != std::string::npos ) { + modelName = pFile.substr(pos+1, pFile.size() - pos - 1); + folderName = pFile.substr( 0, pos ); + if ( folderName.empty() ) { + pIOHandler->PushDirectory( folderName ); + } + } else { + modelName = pFile; } // process all '\' @@ -161,13 +162,18 @@ void ObjFileImporter::InternReadFile( const std::string& pFile, aiScene* pScene, } // parse the file into a temporary representation - ObjFileParser parser(m_Buffer, strModelName, pIOHandler); + ObjFileParser parser(m_Buffer, modelName, pIOHandler); // And create the proper return structures out of it CreateDataFromImport(parser.GetModel(), pScene); // Clean up allocated storage for the next import m_Buffer.clear(); + + // Pop directory stack + if ( pIOHandler->StackSize() > 0 ) { + pIOHandler->PopDirectory(); + } } // ------------------------------------------------------------------------------------------------ diff --git a/code/ObjFileParser.cpp b/code/ObjFileParser.cpp index b2194a747..346c734fc 100644 --- a/code/ObjFileParser.cpp +++ b/code/ObjFileParser.cpp @@ -61,21 +61,21 @@ const std::string ObjFileParser::DEFAULT_MATERIAL = AI_DEFAULT_MATERIAL_NAME; // ------------------------------------------------------------------- // Constructor with loaded data and directories. -ObjFileParser::ObjFileParser(std::vector &Data,const std::string &strModelName, IOSystem *io ) : - m_DataIt(Data.begin()), - m_DataItEnd(Data.end()), +ObjFileParser::ObjFileParser(std::vector &data,const std::string &modelName, IOSystem *io ) : + m_DataIt(data.begin()), + m_DataItEnd(data.end()), m_pModel(NULL), m_uiLine(0), m_pIO( io ) { - std::fill_n(m_buffer,BUFFERSIZE,0); + std::fill_n(m_buffer,Buffersize,0); // Create the model instance to store all the data m_pModel = new ObjFile::Model(); - m_pModel->m_ModelName = strModelName; + m_pModel->m_ModelName = modelName; // create default material and store it - m_pModel->m_pDefaultMaterial = new ObjFile::Material(); + m_pModel->m_pDefaultMaterial = new ObjFile::Material; m_pModel->m_pDefaultMaterial->MaterialName.Set( DEFAULT_MATERIAL ); m_pModel->m_MaterialLib.push_back( DEFAULT_MATERIAL ); m_pModel->m_MaterialMap[ DEFAULT_MATERIAL ] = m_pModel->m_pDefaultMaterial; @@ -248,20 +248,20 @@ void ObjFileParser::getVector( std::vector &point3d_array ) { } float x, y, z; if( 2 == numComponents ) { - copyNextWord( m_buffer, BUFFERSIZE ); + copyNextWord( m_buffer, Buffersize ); x = ( float ) fast_atof( m_buffer ); - copyNextWord( m_buffer, BUFFERSIZE ); + copyNextWord( m_buffer, Buffersize ); y = ( float ) fast_atof( m_buffer ); z = 0.0; } else if( 3 == numComponents ) { - copyNextWord( m_buffer, BUFFERSIZE ); + copyNextWord( m_buffer, Buffersize ); x = ( float ) fast_atof( m_buffer ); - copyNextWord( m_buffer, BUFFERSIZE ); + copyNextWord( m_buffer, Buffersize ); y = ( float ) fast_atof( m_buffer ); - copyNextWord( m_buffer, BUFFERSIZE ); + copyNextWord( m_buffer, Buffersize ); z = ( float ) fast_atof( m_buffer ); } else { throw DeadlyImportError( "OBJ: Invalid number of components" ); @@ -274,13 +274,13 @@ void ObjFileParser::getVector( std::vector &point3d_array ) { // Get values for a new 3D vector instance void ObjFileParser::getVector3(std::vector &point3d_array) { float x, y, z; - copyNextWord(m_buffer, BUFFERSIZE); + copyNextWord(m_buffer, Buffersize); x = (float) fast_atof(m_buffer); - copyNextWord(m_buffer, BUFFERSIZE); + copyNextWord(m_buffer, Buffersize); y = (float) fast_atof(m_buffer); - copyNextWord( m_buffer, BUFFERSIZE ); + copyNextWord( m_buffer, Buffersize ); z = ( float ) fast_atof( m_buffer ); point3d_array.push_back( aiVector3D( x, y, z ) ); @@ -291,10 +291,10 @@ void ObjFileParser::getVector3(std::vector &point3d_array) { // Get values for a new 2D vector instance void ObjFileParser::getVector2( std::vector &point2d_array ) { float x, y; - copyNextWord(m_buffer, BUFFERSIZE); + copyNextWord(m_buffer, Buffersize); x = (float) fast_atof(m_buffer); - copyNextWord(m_buffer, BUFFERSIZE); + copyNextWord(m_buffer, Buffersize); y = (float) fast_atof(m_buffer); point2d_array.push_back(aiVector2D(x, y)); @@ -306,12 +306,12 @@ void ObjFileParser::getVector2( std::vector &point2d_array ) { // Get values for a new face instance void ObjFileParser::getFace(aiPrimitiveType type) { - copyNextLine(m_buffer, BUFFERSIZE); + copyNextLine(m_buffer, Buffersize); if (m_DataIt == m_DataItEnd) return; char *pPtr = m_buffer; - char *pEnd = &pPtr[BUFFERSIZE]; + char *pEnd = &pPtr[Buffersize]; pPtr = getNextToken(pPtr, pEnd); if (pPtr == pEnd || *pPtr == '\0') return; @@ -468,8 +468,9 @@ void ObjFileParser::getMaterialDesc() // Get next data for material data m_DataIt = getNextToken(m_DataIt, m_DataItEnd); - if (m_DataIt == m_DataItEnd) + if (m_DataIt == m_DataItEnd) { return; + } char *pStart = &(*m_DataIt); while( m_DataIt != m_DataItEnd && !IsLineEnd( *m_DataIt ) ) { @@ -483,14 +484,11 @@ void ObjFileParser::getMaterialDesc() // Search for material std::map::iterator it = m_pModel->m_MaterialMap.find( strName ); - if ( it == m_pModel->m_MaterialMap.end() ) - { + if ( it == m_pModel->m_MaterialMap.end() ) { // Not found, use default material m_pModel->m_pCurrentMaterial = m_pModel->m_pDefaultMaterial; DefaultLogger::get()->error("OBJ: failed to locate material " + strName + ", skipping"); - } - else - { + } else { // Found, using detected material m_pModel->m_pCurrentMaterial = (*it).second; if ( needsNewMesh( strName )) @@ -539,18 +537,26 @@ void ObjFileParser::getMaterialLib() // Check for existence const std::string strMatName(pStart, &(*m_DataIt)); - IOStream *pFile = m_pIO->Open(strMatName); + std::string absName; + if ( m_pIO->StackSize() > 0 ) { + const std::string &path = m_pIO->CurrentDirectory(); + absName = path + strMatName; + } else { + absName = strMatName; + } + //IOStream *pFile = m_pIO->Open( strMatName ); + IOStream *pFile = m_pIO->Open( absName ); if (!pFile ) { - DefaultLogger::get()->error("OBJ: Unable to locate material file " + strMatName); + DefaultLogger::get()->error("OBJ: Unable to locate material file " + strMatName ); m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); return; } // Import material library data from file std::vector buffer; - BaseImporter::TextFileToBuffer(pFile,buffer); + BaseImporter::TextFileToBuffer( pFile, buffer ); m_pIO->Close( pFile ); // Importing the material library diff --git a/code/ObjFileParser.h b/code/ObjFileParser.h index 85f555567..66f378f29 100644 --- a/code/ObjFileParser.h +++ b/code/ObjFileParser.h @@ -62,10 +62,9 @@ class IOSystem; /// \class ObjFileParser /// \brief Parser for a obj waveform file -class ObjFileParser -{ +class ObjFileParser { public: - static const size_t BUFFERSIZE = 4096; + static const size_t Buffersize = 4096; typedef std::vector DataArray; typedef std::vector::iterator DataArrayIt; typedef std::vector::const_iterator ConstDataArrayIt; @@ -137,9 +136,10 @@ private: //! Current line (for debugging) unsigned int m_uiLine; //! Helper buffer - char m_buffer[BUFFERSIZE]; + char m_buffer[Buffersize]; /// Pointer to IO system instance. IOSystem *m_pIO; + /// Path to the current model }; } // Namespace Assimp diff --git a/include/assimp/IOSystem.hpp b/include/assimp/IOSystem.hpp index 4b4d55fd4..81b3e910a 100644 --- a/include/assimp/IOSystem.hpp +++ b/include/assimp/IOSystem.hpp @@ -53,6 +53,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #endif #include "types.h" + +#include + namespace Assimp { class IOStream; @@ -170,10 +173,19 @@ public: */ inline bool ComparePaths (const std::string& one, const std::string& second) const; + + virtual bool PushDirectory( const std::string &path ); + virtual const std::string &CurrentDirectory() const; + virtual size_t StackSize() const; + virtual bool PopDirectory(); + +private: + std::vector m_pathStack; }; // ---------------------------------------------------------------------------- -AI_FORCE_INLINE IOSystem::IOSystem() +AI_FORCE_INLINE IOSystem::IOSystem() : + m_pathStack() { // empty } @@ -220,6 +232,43 @@ inline bool IOSystem::ComparePaths (const std::string& one, } // ---------------------------------------------------------------------------- +inline bool IOSystem::PushDirectory( const std::string &path ) { + if ( path.empty() ) { + return false; + } + + m_pathStack.push_back( path ); + + return true; +} + +// ---------------------------------------------------------------------------- +inline const std::string &IOSystem::CurrentDirectory() const { + if ( m_pathStack.empty() ) { + static const std::string Dummy(""); + return Dummy; + } + return m_pathStack[ m_pathStack.size()-1 ]; +} + +// ---------------------------------------------------------------------------- +inline size_t IOSystem::StackSize() const { + return m_pathStack.size(); +} + +// ---------------------------------------------------------------------------- +inline bool IOSystem::PopDirectory() { + if ( m_pathStack.empty() ) { + return false; + } + + m_pathStack.pop_back(); + + return true; +} + +// ---------------------------------------------------------------------------- + } //!ns Assimp #endif //AI_IOSYSTEM_H_INC diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index a93bcf91f..d3bd490e8 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -24,6 +24,7 @@ SET( TEST_SRCS unit/utGenNormals.cpp unit/utImporter.cpp unit/utImproveCacheLocality.cpp + unit/utIOSystem.cpp unit/utJoinVertices.cpp unit/utLimitBoneWeights.cpp unit/utMaterialSystem.cpp diff --git a/test/unit/utIOSystem.cpp b/test/unit/utIOSystem.cpp new file mode 100644 index 000000000..b44976488 --- /dev/null +++ b/test/unit/utIOSystem.cpp @@ -0,0 +1,94 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2014, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above +copyright notice, this list of conditions and the +following disclaimer. + +* Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the +following disclaimer in the documentation and/or other +materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its +contributors may be used to endorse or promote products +derived from this software without specific prior +written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ +#include "UnitTestPCH.h" + +#include + +using namespace std; +using namespace Assimp; + +static const string Sep = "/"; +class TestIOSystem : public IOSystem { +public: + TestIOSystem() : IOSystem() {} + virtual ~TestIOSystem() {} + virtual bool Exists( const char* ) const { + return true; + } + virtual char getOsSeparator() const { + return Sep[ 0 ]; + } + + virtual IOStream* Open(const char* pFile, const char* pMode = "rb") { + return NULL; + } + + virtual void Close( IOStream* pFile) { + // empty + } +}; + +class IOSystemTest : public ::testing::Test { +public: + virtual void SetUp() { pImp = new TestIOSystem(); } + virtual void TearDown() { delete pImp; } + +protected: + TestIOSystem* pImp; +}; + +/* +virtual bool PushDirectory( const std::string &path ); +virtual const std::string &CurrentDirectory() const; +virtual bool PopDirectory(); +*/ + +TEST_F( IOSystemTest, accessDirectoryStackTest ) { + EXPECT_FALSE( pImp->PopDirectory() ); + EXPECT_EQ( 0, pImp->StackSize() ); + EXPECT_FALSE( pImp->PushDirectory( "" ) ); + std::string path = "test/"; + EXPECT_TRUE( pImp->PushDirectory( path ) ); + EXPECT_EQ( 1, pImp->StackSize() ); + EXPECT_EQ( path, pImp->CurrentDirectory() ); + EXPECT_TRUE( pImp->PopDirectory() ); + EXPECT_EQ( 0, pImp->StackSize() ); +} From e9937ab0f7e8352fbb0db9adeaf46437c193c2a7 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sun, 30 Aug 2015 15:37:56 +0200 Subject: [PATCH 51/51] IOSystem: add missing documentation. --- code/ObjFileParser.cpp | 6 ++---- include/assimp/IOSystem.hpp | 28 ++++++++++++++++++++++------ 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/code/ObjFileParser.cpp b/code/ObjFileParser.cpp index 346c734fc..027d99543 100644 --- a/code/ObjFileParser.cpp +++ b/code/ObjFileParser.cpp @@ -544,12 +544,10 @@ void ObjFileParser::getMaterialLib() } else { absName = strMatName; } - //IOStream *pFile = m_pIO->Open( strMatName ); IOStream *pFile = m_pIO->Open( absName ); - if (!pFile ) - { - DefaultLogger::get()->error("OBJ: Unable to locate material file " + strMatName ); + if (!pFile ) { + DefaultLogger::get()->error( "OBJ: Unable to locate material file " + strMatName ); m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); return; } diff --git a/include/assimp/IOSystem.hpp b/include/assimp/IOSystem.hpp index 81b3e910a..321509de6 100644 --- a/include/assimp/IOSystem.hpp +++ b/include/assimp/IOSystem.hpp @@ -105,18 +105,14 @@ public: * @param pFile Path to the file * @return true if there is a file with this path, else false. */ - virtual bool Exists( const char* pFile) const = 0; - - // ------------------------------------------------------------------- /** @brief Returns the system specific directory separator * @return System specific directory separator */ virtual char getOsSeparator() const = 0; - // ------------------------------------------------------------------- /** @brief Open a new file with a given path. * @@ -142,8 +138,6 @@ public: inline IOStream* Open(const std::string& pFile, const std::string& pMode = std::string("rb")); - - // ------------------------------------------------------------------- /** @brief Closes the given file and releases all resources * associated with it. @@ -174,9 +168,31 @@ public: inline bool ComparePaths (const std::string& one, const std::string& second) const; + // ------------------------------------------------------------------- + /** @brief Pushes a new directory onto the directory stack. + * @param path Path to push onto the stack. + * @return True, when push was successful, false if path is empty. + */ virtual bool PushDirectory( const std::string &path ); + + // ------------------------------------------------------------------- + /** @brief Returns the top directory from the stack. + * @return The directory on the top of the stack. + * Returns empty when no directory was pushed to the stack. + */ virtual const std::string &CurrentDirectory() const; + + // ------------------------------------------------------------------- + /** @brief Returns the number of directories stored on the stack. + * @return The number of directories of the stack. + */ virtual size_t StackSize() const; + + // ------------------------------------------------------------------- + /** @brief Pops the top directory from the stack. + * @return True, when a directory was on the stack. False if no + * directory was on the stack. + */ virtual bool PopDirectory(); private: