Хотя ответ mnuages дает подходящий ответ заголовку (фактически «скрывая» части геометрии), я понял, что этого будет недостаточно, потому что я хочу программно сериализовать оставшуюся геометрию как узел в сцене ,
Чтобы ответить на мой «Вопрос 2», я написал дополнения к классам SceneKit, которые позволили бы мне генерировать новые объекты SCNGeometry с диапазонами примитивов из исходных объектов. Это может быть довольно наивно по отношению к материалам (мои модели используют простые цвета, этот код, возможно, еще не обрабатывает другие текстуры); и он может не работать для примитивов, кроме треугольных полосок.
код доступен в GitHub на https://github.com/Fyrestead/PartialGeometry
Для полноты, начальная версия наклеена ниже.
SCNGeometry дополнение:
//
// SCNGeometry.swift
//
// Created by Shon Frazier on 11/22/14.
// Copyright (c) 2014 Fyrestead, LLC. All rights reserved.
//
import Foundation
import SceneKit
let allSemantics = [
SCNGeometrySourceSemanticVertex,
SCNGeometrySourceSemanticNormal,
SCNGeometrySourceSemanticColor,
SCNGeometrySourceSemanticTexcoord,
SCNGeometrySourceSemanticVertexCrease,
SCNGeometrySourceSemanticEdgeCrease,
SCNGeometrySourceSemanticBoneWeights,
SCNGeometrySourceSemanticBoneIndices
]
extension SCNGeometry {
func geometryForRangeOfPrimitives(range: NSRange) -> SCNGeometry? {
var primitiveType: SCNGeometryPrimitiveType
var allElements: [SCNGeometryElement] = [SCNGeometryElement]()
for i in 0..<self.geometryElementCount {
let element = self.geometryElementAtIndex(i)
if element == nil {
continue
}
var newElement = element!.geometryElementForRangeOfPrimitives(range)
if newElement != nil {
allElements += [newElement!]
}
}
var allSources: [SCNGeometrySource] = [SCNGeometrySource]()
for semantic in allSemantics {
var sources = self.geometrySourcesForSemantic(semantic)
if sources == nil {
continue
}
for source in sources! as [SCNGeometrySource] {
var range: NSRange = NSRange(location: 0, length: 5)
let newSource = source.geometrySourceForRangeOfPrimitives(range, primitiveType: SCNGeometryPrimitiveType.TriangleStrip)
allSources += [newSource!]
}
}
var newGeometry = SCNGeometry(sources: allSources, elements: allElements)
newGeometry.materials = materials
return newGeometry
}
}
SCNGeometryElement дополнение:
//
// SCNGeometryElement.swift
//
// Created by Shon Frazier on 11/23/14.
// Copyright (c) 2014 Fyrestead, LLC. All rights reserved.
//
import Foundation
import SceneKit
extension SCNGeometryElement {
func geometryElementForRangeOfPrimitives(range: NSRange) -> SCNGeometryElement? {
if data == nil {
return nil
}
let newCount = range.length
let newLocation = range.location * bytesPerIndex
let newLength = range.length * bytesPerIndex
let newRange = NSRange(location: newLocation, length: newLength)
let newData = data!.subdataWithRange(newRange)
let newElement = SCNGeometryElement(
data: newData,
primitiveType: primitiveType,
primitiveCount: newCount,
bytesPerIndex: bytesPerIndex
)
return newElement
}
}
SCNGeometrySource дополнение:
//
// SCNGeometrySource.swift
//
// Created by Shon Frazier on 11/23/14.
// Copyright (c) 2014 Fyrestead, LLC. All rights reserved.
//
import Foundation
import SceneKit
extension SCNGeometrySource {
/* Preserves use of existing data buffer by changing only the offset */
func geometrySourceForRangeOfVectors(range: NSRange) -> SCNGeometrySource? {
if data == nil {
return nil
}
let newOffset = dataOffset + range.location * (dataStride + bytesPerComponent * componentsPerVector)
return SCNGeometrySource(
data: data!,
semantic: semantic,
vectorCount: range.length,
floatComponents: floatComponents,
componentsPerVector: componentsPerVector,
bytesPerComponent: bytesPerComponent,
dataOffset: newOffset,
dataStride: dataStride)
}
func geometrySourceForRangeOfPrimitives(range: NSRange, primitiveType: SCNGeometryPrimitiveType) -> SCNGeometrySource? {
var newGSource: SCNGeometrySource?
switch primitiveType {
case .TriangleStrip, .Point:
newGSource = geometrySourceForRangeOfVectors(range)
case .Triangles:
let newRange = NSRange(location: range.location * 3, length: range.length * 3)
newGSource = geometrySourceForRangeOfVectors(newRange)
case .Line:
let newRange = NSRange(location: range.location * 2, length: range.length * 2)
newGSource = geometrySourceForRangeOfVectors(newRange)
}
return newGSource
}
}
Насколько я могу судить, это файл STEP, который определяет геометрию неправильно. Я не знаю, является ли это преднамеренным (возможно, способ побудить людей покупать программное обеспечение для моделирования производителя?Я не знаю ...), или если человек, делающий экспорт, просто ошибся. Во всяком случае, я думаю, что с тех пор я решил просто «спрятать», это не мое намерение. Мне нужно сериализовать выбранную геометрию. – Shon