2014-11-25 2 views
1

У меня есть модель робота KUKA в формате DAE, преобразованная из STEP. Модель сегментирована материалом (только плоский цвет) для детей корневого узла. Например, все части, рассматриваемые роботизированным плечом, включены вместе как единый объект геометрии и применяется зеленый материал. Основными элементами являются одна большая треугольная полоса.Скрытие треугольников в треугольной полосе? (Скрывая части модели программно)

Мне нужно отделить все части робота, чтобы я мог анимировать их правильно. Есть визуальные промежутки между большинством частей, которые я планирую разделить. Моя первая мысль заключалась в том, чтобы искать пробелы в полосе треугольника, но я не знаю, как определить, где расположены промежутки. (Следствие: как может быть треугольная полоска?)

Вторая мысль заключалась в том, чтобы выбирать диапазоны элементов для рендеринга (бинарный стиль поиска, я полагаю, ручная настройка номеров или с помощью экранного элемента управления). Это было бы наиболее полезно в тех местах, где геометрия визуально смежна, но части должны разделяться.

Вопрос 1: существует ли способ определения наличия разрывов в полосе треугольника?

Вопрос 2: существует ли API для выбора подмножества элементов для рендеринга? Конечно, можно было бы написать это, но выглядит как много работы (выбор элементов, связанных источников, картирование текстур, вероятно, будет прав) ...

ответ

0

Хотя ответ 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 
    } 

} 
0

SceneKit не предлагает инструменты для проверки топологии вашей сетки и обнаруживать пробелы. Если ваша оригинальная модель не имеет этих пробелов, попробуйте найти проблему в конвертере STEP to DAE.

Нет удобного метода для рисования только некоторых элементов вашей геометрии. Создание новой геометрии с помощью только тех элементов, которые вас интересуют довольно легко. Если вы хотите что-то быстрое и грязное, вы также можете написать SCNProgram, который ничего не делает в вершинном шейдере и отбрасывает фрагмент в шейдере фрагмента. Создайте массив материалов в соответствии с вашими потребностями и установите его в геометрию.

+0

Насколько я могу судить, это файл STEP, который определяет геометрию неправильно. Я не знаю, является ли это преднамеренным (возможно, способ побудить людей покупать программное обеспечение для моделирования производителя?Я не знаю ...), или если человек, делающий экспорт, просто ошибся. Во всяком случае, я думаю, что с тех пор я решил просто «спрятать», это не мое намерение. Мне нужно сериализовать выбранную геометрию. – Shon

 Смежные вопросы

  • Нет связанных вопросов^_^