Skip to content

Commit

Permalink
Merge pull request #9 from ctreffs/import-export
Browse files Browse the repository at this point in the history
Add import export formats
  • Loading branch information
ctreffs authored Feb 1, 2022
2 parents 069f7b0 + 4dc20d6 commit 988de72
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 61 deletions.
30 changes: 2 additions & 28 deletions Sources/Assimp/AiFace.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,35 +18,9 @@ public struct AiFace {
/// Number of indices defining this face.
///
/// The maximum value for this member is #AI_MAX_FACE_INDICES.
public var numIndices: Int {
Int(face.mNumIndices)
}
public lazy var numIndices: Int = .init(face.mNumIndices)

/// Pointer to the indices array.
/// Size of the array is given in numIndices.
public var indices: [UInt32] {
guard numIndices > 0 else {
return []
}

let indices = [UInt32]((0 ..< numIndices).compactMap { face.mIndices[$0] })

assert(indices.count == numIndices)

return indices
}
}

extension AiFace: Equatable {
public static func == (lhs: AiFace, rhs: AiFace) -> Bool {
lhs.indices == rhs.indices &&
lhs.numIndices == rhs.numIndices
}
}

extension AiFace: Hashable {
public func hash(into hasher: inout Hasher) {
hasher.combine(indices)
hasher.combine(numIndices)
}
public lazy var indices: [UInt32] = Array(UnsafeBufferPointer(start: face.mIndices, count: numIndices))
}
106 changes: 106 additions & 0 deletions Sources/Assimp/Assimp.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
//
// Assimp.swift
// SwiftAssimp
//
// Copyright © 2019-2022 Christian Treffs. All rights reserved.
// Licensed under BSD 3-Clause License. See LICENSE file for details.

@_implementationOnly import CAssimp

public enum Assimp {
static func canImportFileExtension(_ fileExtension: String) -> Bool { aiGetImporterDesc(fileExtension.lowercased()) != nil }

static func getImporterDescriptor(for fileExtension: String) -> AiImporterDesc? { AiImporterDesc(aiGetImporterDesc(fileExtension.lowercased())?.pointee) }

static func importFormats() -> [AiImporterDesc] {
let count = aiGetImportFormatCount()

guard count > 0 else {
return []
}

return (0 ..< count)
.compactMap { AiImporterDesc(aiGetImportFormatDescription($0)?.pointee) }
}

static func importFileExtensions() -> [String] {
importFormats().flatMap(\.fileExtensions).sorted()
}

static func exportFormats() -> [AiExporterDesc] {
let count = aiGetExportFormatCount()

guard count > 0 else {
return []
}

return (0 ..< count)
.compactMap { AiExporterDesc(aiGetExportFormatDescription($0)?.pointee) }
}

static func exportFileExtensions() -> [String] {
exportFormats().map(\.fileExtension).sorted()
}
}

public struct AiImporterDesc: Equatable {
public let name: String
public let author: String
public let maintainer: String
public let comments: String
public let flags: AiImporterFlags
public let major: Range<Int>
public let minor: Range<Int>
public let fileExtensions: [String]

init(_ desc: aiImporterDesc) {
name = String(cString: desc.mName)
author = String(cString: desc.mAuthor)
maintainer = String(cString: desc.mMaintainer)
comments = String(cString: desc.mComments)
flags = AiImporterFlags(rawValue: desc.mFlags)
major = Range<Int>(uncheckedBounds: (lower: Int(desc.mMinMajor), upper: Int(desc.mMaxMajor)))
minor = Range<Int>(uncheckedBounds: (lower: Int(desc.mMinMinor), upper: Int(desc.mMaxMinor)))
fileExtensions = String(cString: desc.mFileExtensions).split(separator: " ").map(String.init)
}

init?(_ desc: aiImporterDesc?) {
guard let desc = desc else {
return nil
}
self.init(desc)
}
}

public struct AiImporterFlags: Equatable, RawRepresentable {
public let rawValue: UInt32

public init(rawValue: UInt32) {
self.rawValue = rawValue
}

public static let supportTextFlavour = AiImporterFlags(rawValue: aiImporterFlags_SupportTextFlavour.rawValue)
public static let supportBinaryFlavour = AiImporterFlags(rawValue: aiImporterFlags_SupportBinaryFlavour.rawValue)
public static let supportCompressedFlavour = AiImporterFlags(rawValue: aiImporterFlags_SupportCompressedFlavour.rawValue)
public static let limitedSupport = AiImporterFlags(rawValue: aiImporterFlags_LimitedSupport.rawValue)
public static let experimental = AiImporterFlags(rawValue: aiImporterFlags_Experimental.rawValue)
}

public struct AiExporterDesc: Equatable {
public let id: String
public let description: String
public let fileExtension: String

init(_ desc: aiExportFormatDesc) {
id = String(cString: desc.id)
description = String(cString: desc.description)
fileExtension = String(cString: desc.fileExtension)
}

init?(_ desc: aiExportFormatDesc?) {
guard let desc = desc else {
return nil
}
self.init(desc)
}
}
14 changes: 14 additions & 0 deletions Tests/AssimpTests/AssimpTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,20 @@ final class AssimpTests: XCTestCase {
XCTAssertEqual(SIMD2<Float>(aiVector2D(x: 5.6, y: 3.4)), SIMD2<Float>(5.6, 3.4))
}

func testImportFormats() {
XCTAssertTrue(Assimp.canImportFileExtension("obj"))
XCTAssertTrue(Assimp.canImportFileExtension("dae"))
XCTAssertTrue(Assimp.canImportFileExtension("gltf"))
XCTAssertFalse(Assimp.canImportFileExtension("txt"))
XCTAssertFalse(Assimp.canImportFileExtension("psd"))

XCTAssertGreaterThanOrEqual(Assimp.importFileExtensions().count, 70)
}

func testExportFormats() {
XCTAssertGreaterThanOrEqual(Assimp.exportFileExtensions().count, 20)
}

func testLoadAiSceneDAE() throws {

let fileURL = try Resource.load(.duck_dae)
Expand Down
25 changes: 0 additions & 25 deletions Tests/AssimpTests/XCTestManifests.swift

This file was deleted.

8 changes: 0 additions & 8 deletions Tests/LinuxMain.swift

This file was deleted.

0 comments on commit 988de72

Please sign in to comment.