【问题标题】:Hiding triangles in a triangle strip? (Hiding parts of a model programmatically)在三角形条中隐藏三角形? (以编程方式隐藏模型的一部分)
【发布时间】:2014-12-02 21:41:44
【问题描述】:

我有一个从 STEP 转换为 DAE 格式的 KUKA 机器人模型。该模型由材料(只是一种平面颜色)分割成根节点的子节点。例如,所有被认为是机械臂的部件都作为单个几何对象包含在一起,并应用了绿色材料。底层元素是一个大三角形带。

我需要分离机器人的所有部分,以便正确设置它们的动画。我计划分离的大部分部分之间存在视觉差距。我的第一个想法是寻找三角形带中的间隙,但我不知道如何判断间隙的位置。 (推论:三角带怎么会有缝隙?)

第二个想法是选择要渲染的元素范围(我想是二进制搜索样式,手动调整数字或使用屏幕控件。)这在几何图形在视觉上相邻的地方最有用,但部分需要分开。

问题一:有什么方法可以判断三角条的缝隙在哪里?

问题 2:是否存在用于选择要呈现的元素子集的 API?写这个当然可以,但看起来需要做很多工作(选择元素、相关来源、纹理映射可能会是正确的......)

【问题讨论】:

    标签: swift osx-yosemite scenekit


    【解决方案1】:

    SceneKit 不提供检查网格拓扑和检测间隙的工具。如果您的原始模型没有这些差距,那么应该尝试在您的 STEP 到 DAE 转换器中找到问题。

    没有方便的方法来仅绘制几何图形的某些元素。仅使用您感兴趣的元素创建一个新的几何图形相当容易。如果你想要一些快速而肮脏的东西,你也可以写一个SCNProgram,它在顶点着色器中什么都不做,并在片段着色器中丢弃片段。根据您的需要创建一个材质数组并将其设置为几何体。

    【讨论】:

    • 据我所知,是 STEP 文件错误地指定了几何图形。我不知道这是否是故意的(也许是一种鼓励人们购买制造商的模拟软件的方式?我不知道……)还是进行出口的人只是犯了一个错误。无论如何,我想我已经决定简单地“隐藏”不是我的意图。我需要序列化选定的几何图形。
    【解决方案2】:

    虽然 mnuages 的回答为标题提供了合适的答案(实际上是“隐藏”几何的一部分),但我意识到这还不够,因为我想以编程方式将剩余的几何序列化为场景中的节点。

    为了回答我的“问题 2”,我在 SceneKit 类中添加了一些内容,这些内容可以让我生成新的 SCNGeometry 对象,其中包含原始对象的基元范围。它在材质方面可能相当幼稚(我的模型使用简单的颜色;此代码可能尚未正确处理其他纹理);它可能不适用于三角形条带以外的图元。

    代码可在 GitHub 上https://github.com/Fyrestead/PartialGeometry 获得

    为了完整起见,下面贴的是初始版本。

    SCNG几何加法:

    //
    //  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
        }
    }
    

    SCNGeometry 元素添加:

    //
    //  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
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-17
      • 1970-01-01
      • 2018-02-11
      • 1970-01-01
      相关资源
      最近更新 更多