PageRenderTime 50ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/apps/experiments/3DViewer/src/main/java/com/javafx/experiments/importers/maya/MPath.java

https://bitbucket.org/rbair/rbair-controls-8
Java | 527 lines | 402 code | 66 blank | 59 comment | 89 complexity | 1fd6186df1fa07923ed0f03c620d3410 MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-2.1, GPL-2.0, LGPL-2.0
  1. /*
  2. * Copyright (c) 2010, 2013 Oracle and/or its affiliates.
  3. * All rights reserved. Use is subject to license terms.
  4. *
  5. * This file is available and licensed under the following license:
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * - Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * - Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in
  15. * the documentation and/or other materials provided with the distribution.
  16. * - Neither the name of Oracle Corporation nor the names of its
  17. * contributors may be used to endorse or promote products derived
  18. * from this software without specific prior written permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  23. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  24. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  25. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  26. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  28. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  30. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. */
  32. package com.javafx.experiments.importers.maya;
  33. import java.util.ArrayList;
  34. import java.util.List;
  35. import com.javafx.experiments.importers.maya.values.MArray;
  36. import com.javafx.experiments.importers.maya.values.MData;
  37. import com.javafx.experiments.importers.maya.values.MFloat2Array;
  38. import com.javafx.experiments.importers.maya.values.MFloat3Array;
  39. import com.javafx.experiments.importers.maya.values.MFloatArray;
  40. import com.javafx.experiments.importers.maya.values.MInt3Array;
  41. import com.javafx.experiments.importers.maya.values.MIntArray;
  42. // ry => r[1];
  43. public class MPath implements Comparable {
  44. static abstract class Component implements Comparable {
  45. public MData apply(MData data) {
  46. return null;
  47. }
  48. public MData apply(MNode node) {
  49. return null;
  50. }
  51. }
  52. // Index < Slice < Select in ordering
  53. static class Index extends Component {
  54. int index;
  55. public String toString() {
  56. return "[" + index + "]";
  57. }
  58. public Index(int i) {
  59. index = i;
  60. }
  61. public MData apply(MData data) {
  62. data.setSize(index + 1);
  63. return data.getData(index);
  64. }
  65. public int getIndex() {
  66. return index;
  67. }
  68. public boolean equals(Object other) {
  69. if (!(other instanceof Index)) {
  70. return false;
  71. }
  72. return index == ((Index) other).index;
  73. }
  74. public int hashCode() {
  75. return 11 + 17 * index;
  76. }
  77. public int compareTo(Object arg) {
  78. if (arg instanceof Index) {
  79. return index - ((Index) arg).index;
  80. }
  81. if (arg instanceof Component) {
  82. return -1;
  83. }
  84. throw new ClassCastException(arg.getClass().getName());
  85. }
  86. }
  87. static class Slice extends Component {
  88. public String toString() {
  89. return "[" + start + ":" + end + "]";
  90. }
  91. int start, end;
  92. public Slice(int i, int j) {
  93. start = i;
  94. end = j;
  95. }
  96. public MData apply(MData data) {
  97. data.setSize(end + 1);
  98. return data.getData(start, end);
  99. }
  100. public boolean equals(Object arg) {
  101. if (!(arg instanceof Slice)) {
  102. return false;
  103. }
  104. Slice other = (Slice) arg;
  105. return (start == other.start &&
  106. end == other.end);
  107. }
  108. public int hashCode() {
  109. return 11 + 17 * start + 23 * end;
  110. }
  111. public int compareTo(Object arg) {
  112. if (arg instanceof Slice) {
  113. Slice other = (Slice) arg;
  114. int diff = start - other.start;
  115. if (diff != 0) {
  116. return diff;
  117. }
  118. return end - other.end;
  119. }
  120. if (arg instanceof Index) {
  121. return 1;
  122. }
  123. if (arg instanceof Select) {
  124. return -1;
  125. }
  126. throw new ClassCastException(arg.getClass().getName());
  127. }
  128. }
  129. static class Select extends Component {
  130. public String toString() {
  131. return "." + name;
  132. }
  133. String name;
  134. public Select(String n) {
  135. name = n;
  136. }
  137. public MData apply(MData data) {
  138. return data.getData(name);
  139. }
  140. public MData apply(MNode node) {
  141. return node.getAttrDirect(name);
  142. }
  143. public boolean equals(Object arg) {
  144. if (!(arg instanceof Select)) {
  145. return false;
  146. }
  147. Select other = (Select) arg;
  148. return (name.equals(other.name));
  149. }
  150. public int hashCode() {
  151. return name.hashCode();
  152. }
  153. public int compareTo(Object arg) {
  154. if (arg instanceof Select) {
  155. return name.compareTo(((Select) arg).name);
  156. }
  157. if (arg instanceof Component) {
  158. return 1;
  159. }
  160. throw new ClassCastException(arg.getClass().getName());
  161. }
  162. }
  163. // A Path always exists within the context of a given node
  164. MNode node;
  165. List<Component> components = new ArrayList();
  166. private void add(Component comp) {
  167. components.add(comp);
  168. }
  169. // Used to canonicalize for example in Mesh:
  170. // .iog.og[n] -> .iog[0].og[n]
  171. private boolean selectsArray() {
  172. if (components.size() == 0) {
  173. return false;
  174. }
  175. // If we're already doing an array indexing as the last
  176. // operation in the path, state that we aren't selecting an
  177. // array
  178. if (components.get(components.size() - 1) instanceof Index) {
  179. return false;
  180. }
  181. MData data = apply();
  182. if (data == null) {
  183. return false;
  184. }
  185. // Should we be using MDataType instead for these type queries?
  186. return ((data instanceof MArray) ||
  187. (data instanceof MFloatArray) ||
  188. (data instanceof MFloat2Array) ||
  189. (data instanceof MFloat3Array) ||
  190. (data instanceof MIntArray) ||
  191. (data instanceof MInt3Array));
  192. }
  193. private String canonicalize(String name) {
  194. // FIXME: do we need to do this for deeper data types too?
  195. return node.getCanonicalName(name);
  196. }
  197. public MPath(MEnv env, String path) {
  198. String nodeName;
  199. int i = path.indexOf(".");
  200. if (i > 0) {
  201. nodeName = path.substring(0, i);
  202. path = path.substring(i);
  203. } else {
  204. nodeName = path;
  205. }
  206. node = env.findNode(nodeName);
  207. if (i > 0) {
  208. addComponents(path);
  209. }
  210. }
  211. public MPath(MNode node, String path) {
  212. this.node = node;
  213. addComponents(path);
  214. }
  215. // For copying
  216. private MPath(MNode node) {
  217. this.node = node;
  218. }
  219. public boolean equals(Object arg) {
  220. if (!(arg instanceof MPath)) {
  221. return false;
  222. }
  223. MPath other = (MPath) arg;
  224. return (node == other.node &&
  225. components.equals(other.components));
  226. }
  227. public int hashCode() {
  228. int hashCode = 0;
  229. for (Component comp : components) {
  230. hashCode += 17 * comp.hashCode();
  231. }
  232. return hashCode;
  233. /*
  234. if (node == null) {
  235. return 0;
  236. }
  237. return node.hashCode();
  238. */
  239. }
  240. public int compareTo(Object arg) {
  241. MPath other = (MPath) arg;
  242. if (node != other.node) {
  243. return node.hashCode() - other.node.hashCode();
  244. }
  245. int sz = Math.min(components.size(), other.components.size());
  246. for (int i = 0; i < sz; i++) {
  247. int diff = components.get(i).compareTo(other.components.get(i));
  248. if (diff != 0) {
  249. return diff;
  250. }
  251. }
  252. if (components.size() != other.components.size()) {
  253. return components.size() - other.components.size();
  254. }
  255. return 0;
  256. }
  257. public boolean isValid() {
  258. return getTargetNode() != null;
  259. }
  260. /** Indicates whether this path is a prefix of the given one. */
  261. public boolean isPrefixOf(MPath other) {
  262. if (node != other.node) {
  263. return false;
  264. }
  265. if (components.size() > other.components.size()) {
  266. return false;
  267. }
  268. for (int i = 0; i < components.size(); i++) {
  269. if (!(components.get(i).equals(other.components.get(i)))) {
  270. return false;
  271. }
  272. }
  273. return true;
  274. }
  275. /** Returns the parent path of this one -- i.e., the path with the last component removed. */
  276. public MPath getParentPath() {
  277. MPath res = new MPath(node);
  278. for (int i = 0; i < components.size() - 1; i++) {
  279. res.add(components.get(i));
  280. }
  281. return res;
  282. }
  283. private void addComponents(String path) {
  284. if (node == null) {
  285. return;
  286. }
  287. int mark = 0;
  288. int i = 0;
  289. int len = path.length();
  290. for (; i < len; i++) {
  291. char ch = path.charAt(i);
  292. if (ch == '.') {
  293. if (i - mark > 0) {
  294. String str = path.substring(mark, i);
  295. String str1 = canonicalize(str);
  296. if (str.equals(str1)) {
  297. // Before performing component selection,
  298. // canonicalize connections to arrays to point
  299. // to the zeroth array index
  300. if (selectsArray()) {
  301. add(new Index(0));
  302. }
  303. add(new Select(str1));
  304. } else {
  305. addComponents(str1);
  306. }
  307. }
  308. mark = i + 1;
  309. } else if (ch == '[') {
  310. if (i - mark > 0) {
  311. String str = path.substring(mark, i);
  312. String str1 = canonicalize(str);
  313. if (str.equals(str1)) {
  314. // Before performing component selection,
  315. // canonicalize connections to arrays to point
  316. // to the zeroth array index
  317. if (selectsArray()) {
  318. add(new Index(0));
  319. }
  320. add(new Select(str1));
  321. } else {
  322. addComponents(str1);
  323. }
  324. }
  325. int j = i + 1;
  326. while (true) {
  327. ch = path.charAt(j);
  328. if (ch == ']') {
  329. break;
  330. }
  331. j++;
  332. }
  333. String indexStr = path.substring(i + 1, j);
  334. int colon = indexStr.indexOf(':');
  335. if (colon > 0) {
  336. int start = Integer.parseInt(indexStr.substring(0, colon));
  337. int end = Integer.parseInt(indexStr.substring(colon + 1));
  338. add(new Slice(start, end));
  339. } else {
  340. int index = Integer.parseInt(indexStr);
  341. add(new Index(index));
  342. }
  343. i = j + 1;
  344. if (i < len && path.charAt(i) == '.') {
  345. i++;
  346. }
  347. mark = i;
  348. }
  349. }
  350. if (mark < len && i - mark > 0) {
  351. String str = path.substring(mark, i);
  352. String str1 = canonicalize(str);
  353. if (str.equals(str1)) {
  354. // Before performing component selection,
  355. // canonicalize connections to arrays to point
  356. // to the zeroth array index
  357. if (selectsArray()) {
  358. add(new Index(0));
  359. }
  360. add(new Select(str1));
  361. } else {
  362. addComponents("." + str1);
  363. }
  364. }
  365. }
  366. public MData apply() {
  367. if (components.size() == 0) {
  368. return null;
  369. }
  370. MData data = components.get(0).apply(node);
  371. return apply(1, data);
  372. }
  373. private MData apply(int i, MData data) {
  374. while (i < components.size()) {
  375. if (data == null) {
  376. return null;
  377. }
  378. data = components.get(i++).apply(data);
  379. }
  380. return data;
  381. }
  382. public String toString() {
  383. if (node == null) {
  384. return "[invalid path -- no node]";
  385. } else {
  386. return node.getFullName() + components.toString();
  387. }
  388. }
  389. public MNode getTargetNode() {
  390. return node;
  391. }
  392. int attributeOffset = -1;
  393. MAttribute attr;
  394. int _getAttributeOffset() {
  395. if (attributeOffset == -1) {
  396. String selector = "";
  397. int i = 0;
  398. while (i < components.size()) {
  399. selector += components.get(i).toString();
  400. attr = getTargetNode().getNodeType().getAttribute(selector.substring(1));
  401. if (attr != null) {
  402. attributeOffset = i;
  403. break;
  404. }
  405. i++;
  406. }
  407. }
  408. return attributeOffset;
  409. }
  410. public MAttribute getTargetAttribute(MEnv env) {
  411. _getAttributeOffset();
  412. return attr;
  413. }
  414. public String getComponentSelector() {
  415. int i = 0;
  416. String result = "";
  417. while (i < components.size()) {
  418. result += components.get(i).toString();
  419. i++;
  420. }
  421. return result.substring(1);
  422. }
  423. public String getPathComponent(int i) {
  424. return components.get(i).toString();
  425. }
  426. public String getLastPathComponent() {
  427. return getPathComponent(components.size() - 1);
  428. }
  429. public String getLastSelectionPathComponent() {
  430. for (int i = components.size() - 1; i >= 0; --i) {
  431. Component comp = components.get(i);
  432. if (comp instanceof Select) {
  433. String res = "";
  434. for (int j = i; j < components.size(); j++) {
  435. res += getPathComponent(j);
  436. }
  437. return res;
  438. }
  439. }
  440. return null;
  441. }
  442. public int getLastPathIndex() {
  443. Component component = components.get(components.size() - 1);
  444. if (component instanceof Index) {
  445. return ((Index) component).getIndex();
  446. }
  447. return -1;
  448. }
  449. public String getLastNamedPathComponent() {
  450. for (int i = components.size() - 1; i >= 0; --i) {
  451. Component comp = components.get(i);
  452. if (comp instanceof Select) {
  453. return comp.toString();
  454. }
  455. }
  456. return null;
  457. }
  458. public int size() {
  459. return components.size();
  460. }
  461. }