Integrated from CeeSol Perforce, changelist 203
AppFwk tests. Added rotation to locator. Caf::FrameAnimationControl : Set current frame to 0 if a framecount change makes the current frame invalid
16
Fwk/AppFwk/CMakeLists.txt
Normal file
@ -0,0 +1,16 @@
|
||||
cmake_minimum_required (VERSION 2.8)
|
||||
|
||||
project (CeeApp)
|
||||
|
||||
|
||||
find_package (Qt4 COMPONENTS QtCore QtGui QtMain QtOpenGl REQUIRED)
|
||||
include (${QT_USE_FILE})
|
||||
|
||||
#libraries
|
||||
add_subdirectory(cafProjectDataModel)
|
||||
add_subdirectory(cafUserInterface)
|
||||
|
||||
#executables
|
||||
add_subdirectory(cafTests/cafProjectDataModel_UnitTests)
|
||||
add_subdirectory(cafTests/cafTestApplication)
|
||||
|
943
Fwk/AppFwk/CommonCode/cvfStructGridCutPlane.cpp
Normal file
@ -0,0 +1,943 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2013 Ceetron AS
|
||||
//
|
||||
// This library may be used under the terms of either the GNU General Public License or
|
||||
// the GNU Lesser General Public License as follows:
|
||||
//
|
||||
// GNU General Public License Usage
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
// GNU Lesser General Public License Usage
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
|
||||
#include "cvfBase.h"
|
||||
|
||||
#include "cvfStructGrid.h"
|
||||
#include "cvfStructGridCutPlane.h"
|
||||
#include "cvfStructGridScalarDataAccess.h"
|
||||
|
||||
#include "cvfGeometryBuilderDrawableGeo.h"
|
||||
#include "cvfPrimitiveSetIndexedUInt.h"
|
||||
#include "cvfDebugTimer.h"
|
||||
#include "cvfPlane.h"
|
||||
#include "cvfScalarMapper.h"
|
||||
#include "cvfEdgeKey.h"
|
||||
#include "cvfMeshEdgeExtractor.h"
|
||||
|
||||
#include <map>
|
||||
#include <cstring>
|
||||
|
||||
#include <math.h>
|
||||
|
||||
namespace cvf {
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
/// \class cvf::StructGridCutPlane
|
||||
/// \ingroup StructGrid
|
||||
///
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
|
||||
// Based on description and implementation from Paul Bourke:
|
||||
// http://local.wasp.uwa.edu.au/~pbourke/geometry/polygonise/
|
||||
|
||||
const uint StructGridCutPlane::sm_edgeTable[256] =
|
||||
{
|
||||
0x0 , 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c,
|
||||
0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,
|
||||
0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c,
|
||||
0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90,
|
||||
0x230, 0x339, 0x33 , 0x13a, 0x636, 0x73f, 0x435, 0x53c,
|
||||
0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30,
|
||||
0x3a0, 0x2a9, 0x1a3, 0xaa , 0x7a6, 0x6af, 0x5a5, 0x4ac,
|
||||
0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0,
|
||||
0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c,
|
||||
0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60,
|
||||
0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff , 0x3f5, 0x2fc,
|
||||
0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0,
|
||||
0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55 , 0x15c,
|
||||
0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950,
|
||||
0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc ,
|
||||
0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0,
|
||||
0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc,
|
||||
0xcc , 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0,
|
||||
0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c,
|
||||
0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650,
|
||||
0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc,
|
||||
0x2fc, 0x3f5, 0xff , 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0,
|
||||
0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c,
|
||||
0x36c, 0x265, 0x16f, 0x66 , 0x76a, 0x663, 0x569, 0x460,
|
||||
0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac,
|
||||
0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa , 0x1a3, 0x2a9, 0x3a0,
|
||||
0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c,
|
||||
0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33 , 0x339, 0x230,
|
||||
0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c,
|
||||
0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99 , 0x190,
|
||||
0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c,
|
||||
0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0
|
||||
};
|
||||
|
||||
const int StructGridCutPlane::sm_triTable[256][16] =
|
||||
{
|
||||
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
|
||||
{2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1},
|
||||
{8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
|
||||
{4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1},
|
||||
{3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1},
|
||||
{4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1},
|
||||
{4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
|
||||
{5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1},
|
||||
{2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1},
|
||||
{9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
|
||||
{2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1},
|
||||
{10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1},
|
||||
{4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1},
|
||||
{5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1},
|
||||
{5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1},
|
||||
{10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1},
|
||||
{8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1},
|
||||
{2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1},
|
||||
{7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1},
|
||||
{2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1},
|
||||
{11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1},
|
||||
{5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1},
|
||||
{11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1},
|
||||
{11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1},
|
||||
{5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1},
|
||||
{2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
|
||||
{5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1},
|
||||
{6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1},
|
||||
{3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1},
|
||||
{6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1},
|
||||
{5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
|
||||
{10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1},
|
||||
{6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1},
|
||||
{8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1},
|
||||
{7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1},
|
||||
{3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
|
||||
{5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1},
|
||||
{0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1},
|
||||
{9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1},
|
||||
{8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1},
|
||||
{5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1},
|
||||
{0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1},
|
||||
{6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1},
|
||||
{10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1},
|
||||
{10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1},
|
||||
{8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1},
|
||||
{1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1},
|
||||
{0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1},
|
||||
{10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1},
|
||||
{3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1},
|
||||
{6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1},
|
||||
{9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1},
|
||||
{8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1},
|
||||
{3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1},
|
||||
{6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1},
|
||||
{10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1},
|
||||
{10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1},
|
||||
{2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1},
|
||||
{7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1},
|
||||
{7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1},
|
||||
{2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1},
|
||||
{1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1},
|
||||
{11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1},
|
||||
{8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1},
|
||||
{0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1},
|
||||
{7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
|
||||
{10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
|
||||
{2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
|
||||
{6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1},
|
||||
{7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1},
|
||||
{2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1},
|
||||
{10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1},
|
||||
{10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1},
|
||||
{0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1},
|
||||
{7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1},
|
||||
{6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1},
|
||||
{8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1},
|
||||
{6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1},
|
||||
{4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1},
|
||||
{10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1},
|
||||
{8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1},
|
||||
{1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1},
|
||||
{8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1},
|
||||
{10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1},
|
||||
{4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1},
|
||||
{10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
|
||||
{5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
|
||||
{11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1},
|
||||
{9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
|
||||
{6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1},
|
||||
{7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1},
|
||||
{3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1},
|
||||
{7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1},
|
||||
{3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1},
|
||||
{6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1},
|
||||
{9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1},
|
||||
{1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1},
|
||||
{4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1},
|
||||
{7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1},
|
||||
{6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1},
|
||||
{0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1},
|
||||
{6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1},
|
||||
{0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1},
|
||||
{11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1},
|
||||
{6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1},
|
||||
{5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1},
|
||||
{9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1},
|
||||
{1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1},
|
||||
{10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1},
|
||||
{0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1},
|
||||
{5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1},
|
||||
{10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1},
|
||||
{11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1},
|
||||
{9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1},
|
||||
{7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1},
|
||||
{2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1},
|
||||
{8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1},
|
||||
{9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1},
|
||||
{9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1},
|
||||
{1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1},
|
||||
{5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1},
|
||||
{0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1},
|
||||
{10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1},
|
||||
{2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1},
|
||||
{0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1},
|
||||
{0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1},
|
||||
{9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1},
|
||||
{5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1},
|
||||
{5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1},
|
||||
{8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1},
|
||||
{9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1},
|
||||
{1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1},
|
||||
{3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1},
|
||||
{4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1},
|
||||
{9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1},
|
||||
{11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1},
|
||||
{11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1},
|
||||
{2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1},
|
||||
{9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1},
|
||||
{3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1},
|
||||
{1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1},
|
||||
{4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1},
|
||||
{4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1},
|
||||
{0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1},
|
||||
{1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Constructor
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
StructGridCutPlane::StructGridCutPlane(const StructGridInterface* grid)
|
||||
: m_grid(grid),
|
||||
m_mapScalarSetIndex(UNDEFINED_UINT),
|
||||
m_scalarMapper(NULL),
|
||||
m_mapNodeAveragedScalars(false),
|
||||
m_mustRecompute(true)
|
||||
{
|
||||
CVF_ASSERT(grid);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
StructGridCutPlane::~StructGridCutPlane()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void StructGridCutPlane::setPlane(const Plane& plane)
|
||||
{
|
||||
m_plane = plane;
|
||||
|
||||
m_mustRecompute = true;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void StructGridCutPlane::setMapScalar(uint scalarSetIndex, const ScalarMapper* mapper, bool nodeAveragedScalars)
|
||||
{
|
||||
CVF_ASSERT(mapper);
|
||||
|
||||
m_mapScalarSetIndex = scalarSetIndex;
|
||||
m_scalarMapper = mapper;
|
||||
m_mapNodeAveragedScalars = nodeAveragedScalars;
|
||||
|
||||
m_mustRecompute = true;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Generate cut plane geometry from current configuration
|
||||
///
|
||||
/// \return Reference to created DrawableGeo object. Returns NULL if no cut plane was generated
|
||||
///
|
||||
/// \todo Remove duplicate nodes from returned geometry
|
||||
/// Current implementation is not optimized in any way
|
||||
/// Should set normal from plane normal instead of relying on caller to compute them
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
ref<DrawableGeo> StructGridCutPlane::generateSurface(const cvf::StructGridScalarDataAccess* dataAccessObject)
|
||||
{
|
||||
if (m_mustRecompute)
|
||||
{
|
||||
computeCutPlane(dataAccessObject);
|
||||
m_mustRecompute = false;
|
||||
}
|
||||
|
||||
size_t numVertices = m_vertices.size();
|
||||
size_t numTriangles = m_triangleIndices.size()/3;
|
||||
if (numVertices == 0 || numTriangles == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool doMapScalar = false;
|
||||
if (m_mapScalarSetIndex != UNDEFINED_UINT && m_scalarMapper.notNull())
|
||||
{
|
||||
CVF_ASSERT(numVertices == m_vertexScalars.size());
|
||||
doMapScalar = true;
|
||||
}
|
||||
|
||||
|
||||
ref<Vec3fArray> vertexArr = new Vec3fArray(m_vertices);
|
||||
|
||||
ref<UIntArray> indices = new UIntArray(m_triangleIndices);
|
||||
ref<PrimitiveSetIndexedUInt> primSet = new PrimitiveSetIndexedUInt(PT_TRIANGLES);
|
||||
primSet->setIndices(indices.p());
|
||||
|
||||
ref<cvf::DrawableGeo> geo = new cvf::DrawableGeo;;
|
||||
geo->setVertexArray(vertexArr.p());
|
||||
geo->addPrimitiveSet(primSet.p());
|
||||
|
||||
if (doMapScalar)
|
||||
{
|
||||
CVF_ASSERT(numVertices == m_vertexScalars.size());
|
||||
|
||||
ref<Color3ubArray> vertexColors = new Color3ubArray;
|
||||
ref<Vec2fArray> textureCoords = new Vec2fArray;
|
||||
vertexColors->reserve(numVertices);
|
||||
textureCoords->reserve(numVertices);
|
||||
size_t i;
|
||||
for (i = 0; i < numVertices; i++)
|
||||
{
|
||||
Color3ub clr = m_scalarMapper->mapToColor(m_vertexScalars[i]);
|
||||
vertexColors->add(clr);
|
||||
|
||||
Vec2f texCoord = m_scalarMapper->mapToTextureCoord(m_vertexScalars[i]);
|
||||
textureCoords->add(texCoord);
|
||||
}
|
||||
|
||||
geo->setColorArray(vertexColors.p());
|
||||
geo->setTextureCoordArray(textureCoords.p());
|
||||
}
|
||||
|
||||
//Trace::show("generateSurface(): Vertices:%d TriConns:%d Tris:%d", vertexArr->size(), indices->size(), indices->size()/3);
|
||||
|
||||
return geo;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
ref<DrawableGeo> StructGridCutPlane::generateMesh(const cvf::StructGridScalarDataAccess* dataAccessObject)
|
||||
{
|
||||
if (m_mustRecompute)
|
||||
{
|
||||
computeCutPlane(dataAccessObject);
|
||||
m_mustRecompute = false;
|
||||
}
|
||||
|
||||
size_t numVertices = m_vertices.size();
|
||||
size_t numLines = m_meshLineIndices.size()/2;
|
||||
if (numVertices == 0 || numLines == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MeshEdgeExtractor ee;
|
||||
ee.addPrimitives(2, &m_meshLineIndices[0], m_meshLineIndices.size());
|
||||
|
||||
ref<UIntArray> indices = ee.lineIndices();
|
||||
ref<PrimitiveSetIndexedUInt> primSet = new PrimitiveSetIndexedUInt(PT_LINES);
|
||||
primSet->setIndices(indices.p());
|
||||
|
||||
ref<Vec3fArray> vertexArr = new Vec3fArray(m_vertices);
|
||||
|
||||
ref<cvf::DrawableGeo> geo = new cvf::DrawableGeo;;
|
||||
geo->setVertexArray(vertexArr.p());
|
||||
geo->addPrimitiveSet(primSet.p());
|
||||
|
||||
//Trace::show("generateMesh(): Vertices:%d LineConns:%d Lines:%d", vertexArr->size(), indices->size(), indices->size()/2);
|
||||
|
||||
return geo;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Generate surface representation of the specified cut plane
|
||||
///
|
||||
/// \note Will compute normals before returning geometry
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void StructGridCutPlane::computeCutPlane(const cvf::StructGridScalarDataAccess* dataAccessObject)
|
||||
{
|
||||
if (!dataAccessObject) return;
|
||||
|
||||
DebugTimer tim("");
|
||||
|
||||
bool doMapScalar = false;
|
||||
if (m_mapScalarSetIndex != UNDEFINED_UINT && m_scalarMapper.notNull())
|
||||
{
|
||||
doMapScalar = true;
|
||||
}
|
||||
|
||||
size_t cellCountI = m_grid->cellCountI();
|
||||
size_t cellCountJ = m_grid->cellCountJ();
|
||||
size_t cellCountK = m_grid->cellCountK();
|
||||
|
||||
// Clear any current data
|
||||
m_vertices.clear();
|
||||
m_vertexScalars.clear();
|
||||
m_triangleIndices.clear();
|
||||
m_meshLineIndices.clear();
|
||||
|
||||
|
||||
// The indexing conventions for vertices and
|
||||
// edges used in the algorithm:
|
||||
// edg verts
|
||||
// 4-------------5 *------4------* 0 0 - 1
|
||||
// /| /| /| /| 1 1 - 2
|
||||
// / | / | 7/ | 5/ | 2 2 - 3
|
||||
// / | / | |z / 8 / 9 3 3 - 0
|
||||
// 7-------------6 | | /y *------6------* | 4 4 - 5
|
||||
// | | | | |/ | | | | 5 5 - 6
|
||||
// | 0---------|---1 *---x | *------0--|---* 6 6 - 7
|
||||
// | / | / 11 / 10 / 7 7 - 4
|
||||
// | / | / | /3 | /1 8 0 - 4
|
||||
// |/ |/ |/ |/ 9 1 - 5
|
||||
// 3-------------2 *------2------* 10 2 - 6
|
||||
// vertex indices edge indices 11 3 - 7
|
||||
//
|
||||
|
||||
|
||||
size_t k;
|
||||
for (k = 0; k < cellCountK; k++)
|
||||
{
|
||||
size_t j;
|
||||
for (j = 0; j < cellCountJ; j++)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < cellCountI; i++)
|
||||
{
|
||||
size_t cellIndex = m_grid->cellIndexFromIJK(i, j, k);
|
||||
|
||||
Vec3d minCoord;
|
||||
Vec3d maxCoord;
|
||||
m_grid->cellMinMaxCordinates(cellIndex, &minCoord, &maxCoord);
|
||||
|
||||
// Early reject for cells outside clipping box
|
||||
if (m_clippingBoundingBox.isValid())
|
||||
{
|
||||
BoundingBox cellBB(minCoord, maxCoord);
|
||||
if (!m_clippingBoundingBox.intersects(cellBB))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if plane intersects this cell and skip if it doesn't
|
||||
if (!isCellIntersectedByPlane(m_plane, minCoord, maxCoord))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
GridCell cell;
|
||||
|
||||
bool isClipped = false;
|
||||
if (m_clippingBoundingBox.isValid())
|
||||
{
|
||||
if (!m_clippingBoundingBox.contains(minCoord) || !m_clippingBoundingBox.contains(maxCoord))
|
||||
{
|
||||
isClipped = true;
|
||||
|
||||
minCoord.x() = CVF_MAX(minCoord.x(), m_clippingBoundingBox.min().x());
|
||||
minCoord.y() = CVF_MAX(minCoord.y(), m_clippingBoundingBox.min().y());
|
||||
minCoord.z() = CVF_MAX(minCoord.z(), m_clippingBoundingBox.min().z());
|
||||
|
||||
maxCoord.x() = CVF_MIN(maxCoord.x(), m_clippingBoundingBox.max().x());
|
||||
maxCoord.y() = CVF_MIN(maxCoord.y(), m_clippingBoundingBox.max().y());
|
||||
maxCoord.z() = CVF_MIN(maxCoord.z(), m_clippingBoundingBox.max().z());
|
||||
}
|
||||
}
|
||||
|
||||
cell.p[0].set(minCoord.x(), maxCoord.y(), minCoord.z());
|
||||
cell.p[1].set(maxCoord.x(), maxCoord.y(), minCoord.z());
|
||||
cell.p[2].set(maxCoord.x(), minCoord.y(), minCoord.z());
|
||||
cell.p[3].set(minCoord.x(), minCoord.y(), minCoord.z());
|
||||
cell.p[4].set(minCoord.x(), maxCoord.y(), maxCoord.z());
|
||||
cell.p[5].set(maxCoord.x(), maxCoord.y(), maxCoord.z());
|
||||
cell.p[6].set(maxCoord.x(), minCoord.y(), maxCoord.z());
|
||||
cell.p[7].set(minCoord.x(), minCoord.y(), maxCoord.z());
|
||||
|
||||
|
||||
// Fetch scalar values
|
||||
double cellScalarValue = 0;
|
||||
if (doMapScalar)
|
||||
{
|
||||
cellScalarValue = dataAccessObject->cellScalar(cellIndex);
|
||||
|
||||
// If we're doing node averaging we must populate grid cell with scalar values interpolated to the grid points
|
||||
if (m_mapNodeAveragedScalars)
|
||||
{
|
||||
CVF_ASSERT(false); // This is not supported in this code.
|
||||
#if 0
|
||||
// This is not supported now. This is possibly valid code for "neighbour regular grids" (Eg. Rectilinear or regular grids)
|
||||
// but is not general for general struct grids. So the interpolation stuff must be handled specially for each "real" grid type
|
||||
if (isClipped)
|
||||
{
|
||||
double scalarVal;
|
||||
if (dataAccessObject->pointScalar(cell.p[0], &scalarVal)) cell.s[0] = scalarVal;
|
||||
if (dataAccessObject->pointScalar(cell.p[1], &scalarVal)) cell.s[1] = scalarVal;
|
||||
if (dataAccessObject->pointScalar(cell.p[2], &scalarVal)) cell.s[2] = scalarVal;
|
||||
if (dataAccessObject->pointScalar(cell.p[3], &scalarVal)) cell.s[3] = scalarVal;
|
||||
if (dataAccessObject->pointScalar(cell.p[4], &scalarVal)) cell.s[4] = scalarVal;
|
||||
if (dataAccessObject->pointScalar(cell.p[5], &scalarVal)) cell.s[5] = scalarVal;
|
||||
if (dataAccessObject->pointScalar(cell.p[6], &scalarVal)) cell.s[6] = scalarVal;
|
||||
if (dataAccessObject->pointScalar(cell.p[7], &scalarVal)) cell.s[7] = scalarVal;
|
||||
}
|
||||
else
|
||||
{
|
||||
cell.s[0] = dataAccessObject->gridPointScalar(i, j + 1, k);
|
||||
cell.s[1] = dataAccessObject->gridPointScalar(i + 1, j + 1, k);
|
||||
cell.s[2] = dataAccessObject->gridPointScalar(i + 1, j, k);
|
||||
cell.s[3] = dataAccessObject->gridPointScalar(i, j, k);
|
||||
cell.s[4] = dataAccessObject->gridPointScalar(i, j + 1, k + 1);
|
||||
cell.s[5] = dataAccessObject->gridPointScalar(i + 1, j + 1, k + 1);
|
||||
cell.s[6] = dataAccessObject->gridPointScalar(i + 1, j, k + 1);
|
||||
cell.s[7] = dataAccessObject->gridPointScalar(i, j, k + 1);
|
||||
}
|
||||
#else
|
||||
cell.s[0] = HUGE_VAL;
|
||||
cell.s[1] = HUGE_VAL;
|
||||
cell.s[2] = HUGE_VAL;
|
||||
cell.s[3] = HUGE_VAL;
|
||||
cell.s[4] = HUGE_VAL;
|
||||
cell.s[5] = HUGE_VAL;
|
||||
cell.s[6] = HUGE_VAL;
|
||||
cell.s[7] = HUGE_VAL;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Triangles triangles;
|
||||
uint numTriangles = polygonise(m_plane, cell, &triangles);
|
||||
if (numTriangles > 0)
|
||||
{
|
||||
// Add all the referenced vertices
|
||||
// At the same time registering their index in the 'global' vertex list
|
||||
uint globalVertexIndices[12];
|
||||
int iv;
|
||||
for (iv = 0; iv < 12; iv++)
|
||||
{
|
||||
if (triangles.usedVertices[iv])
|
||||
{
|
||||
globalVertexIndices[iv] = static_cast<uint>(m_vertices.size());
|
||||
m_vertices.push_back(Vec3f(triangles.vertices[iv]));
|
||||
|
||||
if (doMapScalar)
|
||||
{
|
||||
if (m_mapNodeAveragedScalars)
|
||||
{
|
||||
m_vertexScalars.push_back(triangles.scalars[iv]);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_vertexScalars.push_back(cellScalarValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
globalVertexIndices[iv] = UNDEFINED_UINT;
|
||||
}
|
||||
}
|
||||
|
||||
// Build triangles from the cell
|
||||
const size_t prevNumTriangleIndices = m_triangleIndices.size();
|
||||
uint t;
|
||||
for (t = 0; t < numTriangles; t++)
|
||||
{
|
||||
m_triangleIndices.push_back(globalVertexIndices[triangles.triangleIndices[3*t]]);
|
||||
m_triangleIndices.push_back(globalVertexIndices[triangles.triangleIndices[3*t + 1]]);
|
||||
m_triangleIndices.push_back(globalVertexIndices[triangles.triangleIndices[3*t + 2]]);
|
||||
}
|
||||
|
||||
// Add mesh line indices
|
||||
addMeshLineIndices(&m_triangleIndices[prevNumTriangleIndices], numTriangles);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Trace::show("Vertices:%d TriConns:%d Tris:%d", m_vertices.size(), m_triangleIndices.size(), m_triangleIndices.size()/3);
|
||||
// tim.reportTimeMS("computeCutPlane()");
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Add mesh line indices by analyzing the triangle indices and only adding 'unique' edges
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void StructGridCutPlane::addMeshLineIndices(const uint* triangleIndices, uint triangleCount)
|
||||
{
|
||||
std::vector<int64> edges;
|
||||
edges.reserve(3*triangleCount);
|
||||
|
||||
std::vector<int64>::iterator it;
|
||||
|
||||
uint t;
|
||||
for (t = 0; t < triangleCount; t++)
|
||||
{
|
||||
uint i;
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
const uint vertexIdx1 = triangleIndices[3*t + i];
|
||||
const uint vertexIdx2 = (i < 2) ? triangleIndices[3*t + i + 1] : triangleIndices[3*t];
|
||||
|
||||
int64 edgeKeyVal = EdgeKey(vertexIdx1, vertexIdx2).toKeyVal();
|
||||
it = find(edges.begin(), edges.end(), edgeKeyVal);
|
||||
if (it == edges.end())
|
||||
{
|
||||
edges.push_back(edgeKeyVal);
|
||||
}
|
||||
else
|
||||
{
|
||||
edges.erase(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (it = edges.begin(); it != edges.end(); ++it)
|
||||
{
|
||||
EdgeKey ek = EdgeKey::fromkeyVal(*it);
|
||||
m_meshLineIndices.push_back(ek.index1());
|
||||
m_meshLineIndices.push_back(ek.index2());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
uint StructGridCutPlane::polygonise(const Plane& plane, const GridCell& cell, Triangles* triangles)
|
||||
{
|
||||
int cubeindex = 0;
|
||||
if (plane.distanceSquared(cell.p[0]) < 0) cubeindex |= 1;
|
||||
if (plane.distanceSquared(cell.p[1]) < 0) cubeindex |= 2;
|
||||
if (plane.distanceSquared(cell.p[2]) < 0) cubeindex |= 4;
|
||||
if (plane.distanceSquared(cell.p[3]) < 0) cubeindex |= 8;
|
||||
if (plane.distanceSquared(cell.p[4]) < 0) cubeindex |= 16;
|
||||
if (plane.distanceSquared(cell.p[5]) < 0) cubeindex |= 32;
|
||||
if (plane.distanceSquared(cell.p[6]) < 0) cubeindex |= 64;
|
||||
if (plane.distanceSquared(cell.p[7]) < 0) cubeindex |= 128;
|
||||
|
||||
if (sm_edgeTable[cubeindex] == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Compute vertex coordinates on the edges where we have intersections
|
||||
if (sm_edgeTable[cubeindex] & 1) triangles->vertices[0] = planeLineIntersection(plane, cell.p[0], cell.p[1], cell.s[0], cell.s[1], &triangles->scalars[0] );
|
||||
if (sm_edgeTable[cubeindex] & 2) triangles->vertices[1] = planeLineIntersection(plane, cell.p[1], cell.p[2], cell.s[1], cell.s[2], &triangles->scalars[1] );
|
||||
if (sm_edgeTable[cubeindex] & 4) triangles->vertices[2] = planeLineIntersection(plane, cell.p[2], cell.p[3], cell.s[2], cell.s[3], &triangles->scalars[2] );
|
||||
if (sm_edgeTable[cubeindex] & 8) triangles->vertices[3] = planeLineIntersection(plane, cell.p[3], cell.p[0], cell.s[3], cell.s[0], &triangles->scalars[3] );
|
||||
if (sm_edgeTable[cubeindex] & 16) triangles->vertices[4] = planeLineIntersection(plane, cell.p[4], cell.p[5], cell.s[4], cell.s[5], &triangles->scalars[4] );
|
||||
if (sm_edgeTable[cubeindex] & 32) triangles->vertices[5] = planeLineIntersection(plane, cell.p[5], cell.p[6], cell.s[5], cell.s[6], &triangles->scalars[5] );
|
||||
if (sm_edgeTable[cubeindex] & 64) triangles->vertices[6] = planeLineIntersection(plane, cell.p[6], cell.p[7], cell.s[6], cell.s[7], &triangles->scalars[6] );
|
||||
if (sm_edgeTable[cubeindex] & 128) triangles->vertices[7] = planeLineIntersection(plane, cell.p[7], cell.p[4], cell.s[7], cell.s[4], &triangles->scalars[7] );
|
||||
if (sm_edgeTable[cubeindex] & 256) triangles->vertices[8] = planeLineIntersection(plane, cell.p[0], cell.p[4], cell.s[0], cell.s[4], &triangles->scalars[8] );
|
||||
if (sm_edgeTable[cubeindex] & 512) triangles->vertices[9] = planeLineIntersection(plane, cell.p[1], cell.p[5], cell.s[1], cell.s[5], &triangles->scalars[9] );
|
||||
if (sm_edgeTable[cubeindex] & 1024) triangles->vertices[10] = planeLineIntersection(plane, cell.p[2], cell.p[6], cell.s[2], cell.s[6], &triangles->scalars[10]);
|
||||
if (sm_edgeTable[cubeindex] & 2048) triangles->vertices[11] = planeLineIntersection(plane, cell.p[3], cell.p[7], cell.s[3], cell.s[7], &triangles->scalars[11]);
|
||||
|
||||
|
||||
// Create the triangles
|
||||
memset(triangles->usedVertices, 0, sizeof(triangles->usedVertices));
|
||||
const int* triConnects = sm_triTable[cubeindex];
|
||||
uint n = 0;
|
||||
while (triConnects[n] != -1)
|
||||
{
|
||||
triangles->triangleIndices[n] = triConnects[n];
|
||||
triangles->usedVertices[triConnects[n]] = true;
|
||||
n++;
|
||||
}
|
||||
|
||||
uint numTriangles = n/3;
|
||||
|
||||
return numTriangles;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Vec3d StructGridCutPlane::planeLineIntersection(const Plane& plane, const Vec3d& p1, const Vec3d& p2, const double s1, const double s2, double* s)
|
||||
{
|
||||
// From http://local.wasp.uwa.edu.au/~pbourke/geometry/planeline/
|
||||
//
|
||||
// P1 (x1,y1,z1) and P2 (x2,y2,z2)
|
||||
//
|
||||
// P = P1 + u (P2 - P1)
|
||||
//
|
||||
// A*x1 + B*y1 + C*z1 + D
|
||||
// u = ---------------------------------
|
||||
// A*(x1-x2) + B*(y1-y2) + C*(z1-z2)
|
||||
|
||||
CVF_ASSERT(s);
|
||||
|
||||
const Vec3d v = p2 - p1;
|
||||
|
||||
double denominator = -(plane.A()*v.x() + plane.B()*v.y() + plane.C()*v.z());
|
||||
if (denominator != 0)
|
||||
{
|
||||
double u = (plane.A()*p1.x() + plane.B()*p1.y() + plane.C()*p1.z() + plane.D())/denominator;
|
||||
if (u > 0.0 && u < 1.0)
|
||||
{
|
||||
*s = s1 + u*(s2 - s1);
|
||||
return (p1 + u*v);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (u >= 1.0)
|
||||
{
|
||||
*s = s2;
|
||||
return p2;
|
||||
}
|
||||
else
|
||||
{
|
||||
*s = s1;
|
||||
return p1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*s = s1;
|
||||
return p1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool StructGridCutPlane::isCellIntersectedByPlane(const Plane& plane, const Vec3d& cellMinCoord, const Vec3d& cellMaxCoord)
|
||||
{
|
||||
// See http://zach.in.tu-clausthal.de/teaching/cg_literatur/lighthouse3d_view_frustum_culling/index.html
|
||||
|
||||
// Start by finding the "positive vertex" and the "negative vertex" relative to plane normal
|
||||
Vec3d pVertex(cellMinCoord);
|
||||
Vec3d nVertex(cellMaxCoord);
|
||||
|
||||
if (plane.A() >= 0)
|
||||
{
|
||||
pVertex.x() = cellMaxCoord.x();
|
||||
nVertex.x() = cellMinCoord.x();
|
||||
}
|
||||
|
||||
if (plane.B() >= 0)
|
||||
{
|
||||
pVertex.y() = cellMaxCoord.y();
|
||||
nVertex.y() = cellMinCoord.y();
|
||||
}
|
||||
|
||||
if (plane.C() >= 0)
|
||||
{
|
||||
pVertex.z() = cellMaxCoord.z();
|
||||
nVertex.z() = cellMinCoord.z();
|
||||
}
|
||||
|
||||
// Chek if both positive and negative vertex are on same side of plane
|
||||
if (plane.distanceSquared(pVertex) < 0)
|
||||
{
|
||||
if (plane.distanceSquared(nVertex) < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (plane.distanceSquared(nVertex) >= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void StructGridCutPlane::setClippingBoundingBox(const BoundingBox& boundingBox)
|
||||
{
|
||||
m_clippingBoundingBox = boundingBox;
|
||||
}
|
||||
|
||||
|
||||
} // namespace cvf
|
||||
|
113
Fwk/AppFwk/CommonCode/cvfStructGridCutPlane.h
Normal file
@ -0,0 +1,113 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2013 Ceetron AS
|
||||
//
|
||||
// This library may be used under the terms of either the GNU General Public License or
|
||||
// the GNU Lesser General Public License as follows:
|
||||
//
|
||||
// GNU General Public License Usage
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
// GNU Lesser General Public License Usage
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cvfPlane.h"
|
||||
#include "cvfBoundingBox.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace cvf {
|
||||
|
||||
class DrawableGeo;
|
||||
class StructGridInterface;
|
||||
class ScalarMapper;
|
||||
class StructGridScalarDataAccess;
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
class StructGridCutPlane : public Object
|
||||
{
|
||||
public:
|
||||
StructGridCutPlane(const StructGridInterface* grid);
|
||||
~StructGridCutPlane();
|
||||
|
||||
void setPlane(const Plane& plane);
|
||||
void setClippingBoundingBox(const BoundingBox& boundingBox);
|
||||
void setMapScalar(uint scalarSetIndex, const ScalarMapper* mapper, bool nodeAveragedScalars);
|
||||
|
||||
ref<DrawableGeo> generateSurface(const cvf::StructGridScalarDataAccess* dataAccessObject);
|
||||
ref<DrawableGeo> generateMesh(const cvf::StructGridScalarDataAccess* dataAccessObject);
|
||||
|
||||
private:
|
||||
struct GridCell
|
||||
{
|
||||
Vec3d p[8]; // Cell's corner coordinates
|
||||
double s[8]; // Scalar values in cell corners
|
||||
};
|
||||
|
||||
struct Triangles
|
||||
{
|
||||
Vec3d vertices[12]; // The vertices, one on each edge in the cell
|
||||
double scalars[12]; // Interpolated scalar values for the vertices
|
||||
bool usedVertices[12]; // Flag to indicate which of the vertices (and scalars) are being referenced by the triangle indices
|
||||
int triangleIndices[15];// Triangle indices (into vertices), max 5 triangles.
|
||||
};
|
||||
|
||||
private:
|
||||
void computeCutPlane(const cvf::StructGridScalarDataAccess* dataAccessObject);
|
||||
void addMeshLineIndices(const uint* triangleIndices, uint triangleCount);
|
||||
static uint polygonise(const Plane& plane, const GridCell& cell, Triangles* triangles);
|
||||
static Vec3d planeLineIntersection(const Plane& plane, const Vec3d& p1, const Vec3d& p2, const double s1, const double s2, double* s);
|
||||
static bool isCellIntersectedByPlane(const Plane& plane, const Vec3d& cellMinCoord, const Vec3d& cellMaxCoord);
|
||||
|
||||
private:
|
||||
cref<StructGridInterface> m_grid;
|
||||
|
||||
Plane m_plane;
|
||||
BoundingBox m_clippingBoundingBox;
|
||||
|
||||
uint m_mapScalarSetIndex; // Index of scalar set that should be mapped onto the cut plane. -1 for no mapping
|
||||
cref<ScalarMapper> m_scalarMapper; // Scalar mapper to use when mapping. Both scalar set index and mapper must be set in order to get scalar mapping
|
||||
bool m_mapNodeAveragedScalars; // If true we'll compute node averaged scalars before mapping them on the cut plane. If false per cell scalars will be mapped.
|
||||
|
||||
bool m_mustRecompute; // Flag to indicate that cut plane must be recomputed
|
||||
std::vector<Vec3f> m_vertices; // Vertices of computed surface
|
||||
std::vector<double> m_vertexScalars; // Scalar values for vertices
|
||||
std::vector<uint> m_triangleIndices; // Triangle connectivities
|
||||
std::vector<uint> m_meshLineIndices; // Mesh line connectivities
|
||||
|
||||
static const uint sm_edgeTable[256];
|
||||
static const int sm_triTable[256][16];
|
||||
};
|
||||
|
||||
}
|
1817
Fwk/AppFwk/Doxygen/Doxyfile
Normal file
@ -163,7 +163,11 @@ int FrameAnimationControl::currentFrame() const
|
||||
void FrameAnimationControl::setNumFrames(int numFrames)
|
||||
{
|
||||
m_numFrames = numFrames < 0 ? 0 : numFrames;
|
||||
|
||||
emit frameCountChanged(m_numFrames);
|
||||
|
||||
if (m_currentFrame >= numFrames ) m_currentFrame = 0; // Should we emit frameChanged ?
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -0,0 +1,37 @@
|
||||
cmake_minimum_required (VERSION 2.8)
|
||||
|
||||
project ( cafProjectDataModel_UnitTests )
|
||||
|
||||
include_directories (
|
||||
${CMAKE_SOURCE_DIR}/cafProjectDataModel
|
||||
${CMAKE_SOURCE_DIR}/cafTests
|
||||
|
||||
#Remove when RigStatistics is out
|
||||
${ResInsight_SOURCE_DIR}/ApplicationCode/ModelVisualization
|
||||
)
|
||||
|
||||
# add the executable
|
||||
add_executable (${PROJECT_NAME}
|
||||
cafPdmBasicTest.cpp
|
||||
cafProjectDataModel_UnitTests.cpp
|
||||
${CMAKE_SOURCE_DIR}/cafTests/gtest/gtest-all.cpp
|
||||
)
|
||||
|
||||
target_link_libraries ( ${PROJECT_NAME}
|
||||
cafProjectDataModel
|
||||
${QT_LIBRARIES}
|
||||
)
|
||||
|
||||
|
||||
# Copy Qt Dlls
|
||||
if (MSVC)
|
||||
set (QTLIBLIST QtCore QtGui )
|
||||
foreach (qtlib ${QTLIBLIST})
|
||||
|
||||
# Debug
|
||||
execute_process(COMMAND cmake -E copy_if_different ${QT_BINARY_DIR}/${qtlib}d4.dll ${CMAKE_CURRENT_BINARY_DIR}/Debug/${qtlib}d4.dll)
|
||||
|
||||
# Release
|
||||
execute_process(COMMAND cmake -E copy_if_different ${QT_BINARY_DIR}/${qtlib}4.dll ${CMAKE_CURRENT_BINARY_DIR}/Release/${qtlib}4.dll)
|
||||
endforeach( qtlib )
|
||||
endif(MSVC)
|
@ -0,0 +1,744 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2013 Ceetron AS
|
||||
//
|
||||
// This library may be used under the terms of either the GNU General Public License or
|
||||
// the GNU Lesser General Public License as follows:
|
||||
//
|
||||
// GNU General Public License Usage
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
// GNU Lesser General Public License Usage
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#include <iostream>
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmObject.h"
|
||||
#include "cafPdmPointer.h"
|
||||
#include "cafPdmDocument.h"
|
||||
|
||||
#include "cafAppEnum.h"
|
||||
#include <memory>
|
||||
#include <QFile>
|
||||
|
||||
|
||||
/// Demo objects to show the usage of the Pdm system
|
||||
|
||||
|
||||
class SimpleObj: public caf::PdmObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
public:
|
||||
SimpleObj()
|
||||
{
|
||||
CAF_PDM_InitObject("Simple Object", "", "", "");
|
||||
|
||||
CAF_PDM_InitField(&m_position, "Position", 8765.2, "Position", "", "", "");
|
||||
CAF_PDM_InitField(&m_dir, "Dir", 123.56, "Direction", "", "", "");
|
||||
CAF_PDM_InitField(&m_up, "Up", 0.0, "Up value", "", "", "" );
|
||||
CAF_PDM_InitFieldNoDefault(&m_numbers, "Numbers", "Important Numbers", "", "", "");
|
||||
}
|
||||
|
||||
/// Assignment and copying of PDM objects is not focus for the features. This is only a
|
||||
/// "would it work" test
|
||||
SimpleObj(const SimpleObj& other)
|
||||
: PdmObject()
|
||||
{
|
||||
CAF_PDM_InitField(&m_position, "Position", 8765.2, "Position", "", "", "");
|
||||
CAF_PDM_InitField(&m_dir, "Dir", 123.56, "Direction", "", "", "");
|
||||
CAF_PDM_InitField(&m_up, "Up", 0.0, "Up value", "", "", "" );
|
||||
CAF_PDM_InitFieldNoDefault(&m_numbers, "Numbers", "Important Numbers", "", "", "");
|
||||
|
||||
m_position = other.m_position;
|
||||
m_dir = other.m_dir;
|
||||
m_up = other.m_up;
|
||||
m_numbers = other.m_numbers;
|
||||
}
|
||||
|
||||
~SimpleObj() {}
|
||||
|
||||
|
||||
caf::PdmField<double> m_position;
|
||||
caf::PdmField<double> m_dir;
|
||||
caf::PdmField<double> m_up;
|
||||
caf::PdmField<std::vector<double> > m_numbers;
|
||||
};
|
||||
CAF_PDM_SOURCE_INIT(SimpleObj, "SimpleObj");
|
||||
|
||||
|
||||
|
||||
class DemoPdmObject: public caf::PdmObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
public:
|
||||
|
||||
DemoPdmObject()
|
||||
{
|
||||
CAF_PDM_InitObject("Demo Object", "", "This object is a demo of the CAF framework", "This object is a demo of the CAF framework");
|
||||
|
||||
CAF_PDM_InitField(&m_doubleField, "BigNumber", 0.0, "Big Number", "",
|
||||
"Enter a big number here",
|
||||
"This is a place you can enter a big real value if you want" );
|
||||
|
||||
CAF_PDM_InitField(&m_intField, "IntNumber", 0, "Small Number","",
|
||||
"Enter some small number here",
|
||||
"This is a place you can enter a small integer value if you want");
|
||||
|
||||
CAF_PDM_InitField(&m_textField, "TextField", QString("ÆØÅ Test text end"), "", "", "", "");
|
||||
CAF_PDM_InitFieldNoDefault(&m_simpleObjPtrField, "SimpleObjPtrField", "", "", "", "");
|
||||
CAF_PDM_InitFieldNoDefault(&m_simpleObjPtrField2, "SimpleObjPtrField2", "", "", "", "");
|
||||
m_simpleObjPtrField2 = new SimpleObj;
|
||||
}
|
||||
|
||||
~DemoPdmObject()
|
||||
{
|
||||
delete m_simpleObjPtrField2();
|
||||
}
|
||||
|
||||
// Fields
|
||||
caf::PdmField<double> m_doubleField;
|
||||
caf::PdmField<int> m_intField;
|
||||
caf::PdmField<QString> m_textField;
|
||||
|
||||
caf::PdmField<SimpleObj*> m_simpleObjPtrField;
|
||||
caf::PdmField<SimpleObj*> m_simpleObjPtrField2;
|
||||
};
|
||||
|
||||
CAF_PDM_SOURCE_INIT(DemoPdmObject, "DemoPdmObject");
|
||||
|
||||
|
||||
class InheritedDemoObj : public DemoPdmObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
public:
|
||||
enum TestEnumType
|
||||
{
|
||||
T1, T2, T3
|
||||
};
|
||||
|
||||
InheritedDemoObj()
|
||||
{
|
||||
CAF_PDM_InitFieldNoDefault(&m_texts, "Texts", "Some words", "", "", "");
|
||||
CAF_PDM_InitFieldNoDefault(&m_testEnumField, "TestEnumValue", "An Enum", "", "", "");
|
||||
CAF_PDM_InitFieldNoDefault(&m_simpleObjectsField, "SimpleObjects", "A child object", "", "", "");
|
||||
|
||||
}
|
||||
|
||||
caf::PdmField<std::vector<QString> > m_texts;
|
||||
caf::PdmField< caf::AppEnum<TestEnumType> > m_testEnumField;
|
||||
caf::PdmPointersField<SimpleObj*> m_simpleObjectsField;
|
||||
|
||||
};
|
||||
CAF_PDM_SOURCE_INIT(InheritedDemoObj, "InheritedDemoObj");
|
||||
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
template<>
|
||||
void AppEnum<InheritedDemoObj::TestEnumType>::setUp()
|
||||
{
|
||||
addItem(InheritedDemoObj::T1, "T1", "An A letter");
|
||||
addItem(InheritedDemoObj::T2, "T2", "A B letter");
|
||||
addItem(InheritedDemoObj::T3, "T3", "A B letter");
|
||||
setDefault(InheritedDemoObj::T1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// This is a testbed to try out different aspects, instead of having a main in a prototype program
|
||||
/// To be disabled when everything gets more mature.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST(BaseTest, Start)
|
||||
{
|
||||
DemoPdmObject* a = new DemoPdmObject;
|
||||
|
||||
caf::PdmObject* demo = caf::PdmObjectFactory::instance()->create("DemoPdmObject");
|
||||
EXPECT_TRUE(demo != NULL);
|
||||
|
||||
QString xml;
|
||||
QXmlStreamWriter xmlStream(&xml);
|
||||
xmlStream.setAutoFormatting(true);
|
||||
|
||||
SimpleObj* s2 = new SimpleObj;
|
||||
caf::PdmPointer<SimpleObj> sp;
|
||||
sp = s2;
|
||||
std::cout << sp.p() << std::endl;
|
||||
|
||||
{
|
||||
SimpleObj s;
|
||||
s.m_dir = 10000;
|
||||
sp = &s;
|
||||
a->m_textField = "Hei og hå";
|
||||
*s2 = s;
|
||||
a->m_simpleObjPtrField = s2;
|
||||
|
||||
s.writeFields(xmlStream);
|
||||
}
|
||||
a->writeFields(xmlStream);
|
||||
caf::PdmObjectGroup og;
|
||||
og.objects.push_back(a);
|
||||
og.objects.push_back(s2);
|
||||
og.writeFields(xmlStream);
|
||||
std::cout << sp.p() << std::endl,
|
||||
|
||||
std::cout << xml.toStdString() << std::endl;
|
||||
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Test of PdmField operations
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST(BaseTest, NormalPdmField)
|
||||
{
|
||||
std::vector<double> testValue;
|
||||
testValue.push_back(1.1);
|
||||
testValue.push_back(1.2);
|
||||
testValue.push_back(1.3);
|
||||
|
||||
std::vector<double> testValue2;
|
||||
testValue2.push_back(2.1);
|
||||
testValue2.push_back(2.2);
|
||||
testValue2.push_back(2.3);
|
||||
|
||||
// Constructors
|
||||
caf::PdmField<std::vector<double> > field2(testValue);
|
||||
EXPECT_EQ(1.3, field2.v()[2]);
|
||||
caf::PdmField<std::vector<double> > field3(field2);
|
||||
EXPECT_EQ(1.3, field3.v()[2]);
|
||||
caf::PdmField<std::vector<double> > field1;
|
||||
EXPECT_EQ(size_t(0), field1().size());
|
||||
|
||||
// Operators
|
||||
EXPECT_FALSE(field1 == field3);
|
||||
field1 = field2;
|
||||
EXPECT_EQ(1.3, field1()[2]);
|
||||
field1 = testValue2;
|
||||
EXPECT_EQ(2.3, field1()[2]);
|
||||
field3 = field1;
|
||||
EXPECT_TRUE(field1 == field3);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Test of PdmField of pointer operations
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
TEST(BaseTest, PointerPdmField)
|
||||
{
|
||||
SimpleObj* testValue = new SimpleObj;
|
||||
testValue->m_numbers.v().push_back(1.1);
|
||||
testValue->m_numbers.v().push_back(1.2);
|
||||
testValue->m_numbers.v().push_back(1.3);
|
||||
|
||||
SimpleObj* testValue2 = new SimpleObj;
|
||||
testValue->m_numbers.v().push_back(2.1);
|
||||
testValue->m_numbers.v().push_back(2.2);
|
||||
testValue->m_numbers.v().push_back(2.3);
|
||||
|
||||
// Constructors
|
||||
caf::PdmField<SimpleObj*> field2(testValue);
|
||||
EXPECT_EQ(testValue, field2.v());
|
||||
caf::PdmField<SimpleObj*> field3(field2);
|
||||
EXPECT_EQ(testValue, field3.v());
|
||||
caf::PdmField<SimpleObj*> field1;
|
||||
EXPECT_EQ((SimpleObj*)0, field1.v());
|
||||
|
||||
// Operators
|
||||
EXPECT_FALSE(field1 == field3);
|
||||
field1 = field2;
|
||||
EXPECT_EQ(testValue, field1);
|
||||
field1 = testValue2;
|
||||
field3 = testValue2;
|
||||
EXPECT_EQ(testValue2, field1);
|
||||
EXPECT_TRUE(field1 == field3);
|
||||
delete testValue;
|
||||
delete testValue2;
|
||||
EXPECT_EQ((SimpleObj*)0, field1);
|
||||
EXPECT_EQ((SimpleObj*)0, field2);
|
||||
EXPECT_EQ((SimpleObj*)0, field3);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Test of PdmPointersField operations
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
TEST(BaseTest, PdmPointersField)
|
||||
{
|
||||
std::vector<caf::PdmFieldHandle*> parentFields;
|
||||
|
||||
InheritedDemoObj* ihd1 = new InheritedDemoObj;
|
||||
|
||||
SimpleObj* s1 = new SimpleObj;
|
||||
SimpleObj* s2 = new SimpleObj;
|
||||
SimpleObj* s3 = new SimpleObj;
|
||||
|
||||
// empty() number 1
|
||||
EXPECT_TRUE(ihd1->m_simpleObjectsField.empty());
|
||||
EXPECT_EQ(size_t(0), ihd1->m_simpleObjectsField.size());
|
||||
|
||||
// push_back()
|
||||
ihd1->m_simpleObjectsField.push_back(s1);
|
||||
ihd1->m_simpleObjectsField.push_back(s2);
|
||||
ihd1->m_simpleObjectsField.push_back(s3);
|
||||
|
||||
s1->parentFields(parentFields);
|
||||
EXPECT_EQ(size_t(1), parentFields.size());
|
||||
parentFields.clear();
|
||||
|
||||
// size()
|
||||
EXPECT_EQ(size_t(3), ihd1->m_simpleObjectsField.size());
|
||||
EXPECT_EQ(size_t(3), ihd1->m_simpleObjectsField.size());
|
||||
|
||||
// operator[]
|
||||
EXPECT_EQ(s2, ihd1->m_simpleObjectsField[1]);
|
||||
EXPECT_EQ(s3, ihd1->m_simpleObjectsField[2]);
|
||||
|
||||
// childObjects
|
||||
std::vector<caf::PdmObject*> objects;
|
||||
ihd1->m_simpleObjectsField.childObjects(&objects);
|
||||
EXPECT_EQ(size_t(3), objects.size());
|
||||
|
||||
// Operator ==, Operator =
|
||||
InheritedDemoObj* ihd2 = new InheritedDemoObj;
|
||||
EXPECT_FALSE(ihd2->m_simpleObjectsField == ihd1->m_simpleObjectsField);
|
||||
ihd2->m_simpleObjectsField = ihd1->m_simpleObjectsField;
|
||||
EXPECT_TRUE(ihd2->m_simpleObjectsField == ihd1->m_simpleObjectsField);
|
||||
|
||||
s1->parentFields(parentFields);
|
||||
EXPECT_EQ(size_t(2), parentFields.size());
|
||||
parentFields.clear();
|
||||
|
||||
// set(), Operator=
|
||||
ihd2->m_simpleObjectsField.set(1, NULL);
|
||||
EXPECT_FALSE(ihd2->m_simpleObjectsField == ihd1->m_simpleObjectsField);
|
||||
EXPECT_TRUE(NULL == ihd2->m_simpleObjectsField[1]);
|
||||
|
||||
s2->parentFields(parentFields);
|
||||
EXPECT_EQ(size_t(1), parentFields.size());
|
||||
parentFields.clear();
|
||||
|
||||
// removeAll(pointer)
|
||||
ihd2->m_simpleObjectsField.removeChildObject(NULL);
|
||||
EXPECT_EQ(size_t(2), ihd2->m_simpleObjectsField.size());
|
||||
EXPECT_EQ(s3, ihd2->m_simpleObjectsField[1]);
|
||||
EXPECT_EQ(s1, ihd2->m_simpleObjectsField[0]);
|
||||
|
||||
// insert()
|
||||
ihd2->m_simpleObjectsField.insert(1, s2);
|
||||
EXPECT_TRUE(ihd2->m_simpleObjectsField == ihd1->m_simpleObjectsField);
|
||||
|
||||
s2->parentFields(parentFields);
|
||||
EXPECT_EQ(size_t(2), parentFields.size());
|
||||
parentFields.clear();
|
||||
|
||||
// erase (index)
|
||||
ihd2->m_simpleObjectsField.erase(1);
|
||||
EXPECT_EQ(size_t(2), ihd2->m_simpleObjectsField.size());
|
||||
EXPECT_EQ(s3, ihd2->m_simpleObjectsField[1]);
|
||||
EXPECT_EQ(s1, ihd2->m_simpleObjectsField[0]);
|
||||
|
||||
s2->parentFields(parentFields);
|
||||
EXPECT_EQ(size_t(1), parentFields.size());
|
||||
parentFields.clear();
|
||||
|
||||
// clear()
|
||||
ihd2->m_simpleObjectsField.clear();
|
||||
EXPECT_EQ(size_t(0), ihd2->m_simpleObjectsField.size());
|
||||
|
||||
s1->parentFields(parentFields);
|
||||
EXPECT_EQ(size_t(1), parentFields.size());
|
||||
parentFields.clear();
|
||||
|
||||
|
||||
}
|
||||
template <>
|
||||
inline void GTestStreamToHelper<QString>(std::ostream* os, const QString& val) {
|
||||
*os << val.toLatin1().data();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Tests the roundtrip: Create, write, read, write and checks that the first and second file are identical
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST(BaseTest, ReadWrite)
|
||||
{
|
||||
QString xmlDocumentContentWithErrors;
|
||||
|
||||
{
|
||||
caf::PdmDocument xmlDoc;
|
||||
|
||||
// Create objects
|
||||
DemoPdmObject* d1 = new DemoPdmObject;
|
||||
DemoPdmObject* d2 = new DemoPdmObject;
|
||||
InheritedDemoObj* id1 = new InheritedDemoObj;
|
||||
InheritedDemoObj* id2 = new InheritedDemoObj;
|
||||
|
||||
SimpleObj* s1 = new SimpleObj;
|
||||
SimpleObj s2;
|
||||
|
||||
s1->m_numbers.v().push_back(1.7);
|
||||
|
||||
// set some values
|
||||
s2.m_numbers.v().push_back(2.4);
|
||||
s2.m_numbers.v().push_back(2.5);
|
||||
s2.m_numbers.v().push_back(2.6);
|
||||
s2.m_numbers.v().push_back(2.7);
|
||||
|
||||
id1->m_texts.v().push_back("Hei");
|
||||
id1->m_texts.v().push_back("og");
|
||||
id1->m_texts.v().push_back("Hå test with whitespace");
|
||||
|
||||
d2->m_simpleObjPtrField = &s2;
|
||||
d2->m_simpleObjPtrField2 = s1;
|
||||
|
||||
id1->m_simpleObjectsField.push_back(s1);
|
||||
id1->m_simpleObjectsField.push_back(&s2);
|
||||
id1->m_simpleObjectsField.push_back(&s2);
|
||||
id1->m_simpleObjectsField.push_back(&s2);
|
||||
|
||||
// Add to document
|
||||
|
||||
xmlDoc.addObject(d1);
|
||||
xmlDoc.addObject(d2);
|
||||
xmlDoc.addObject(s1);
|
||||
xmlDoc.addObject(id1);
|
||||
xmlDoc.addObject(id2);
|
||||
|
||||
// Write file
|
||||
xmlDoc.fileName = "PdmTestFil.xml";
|
||||
xmlDoc.writeFile();
|
||||
|
||||
|
||||
|
||||
{
|
||||
std::vector<caf::PdmPointer<DemoPdmObject> > demoObjs;
|
||||
xmlDoc.objectsByType(&demoObjs);
|
||||
EXPECT_EQ(size_t(4), demoObjs.size());
|
||||
}
|
||||
{
|
||||
std::vector<caf::PdmPointer<InheritedDemoObj> > demoObjs;
|
||||
xmlDoc.objectsByType(&demoObjs);
|
||||
EXPECT_EQ(size_t(2), demoObjs.size());
|
||||
}
|
||||
{
|
||||
std::vector<caf::PdmPointer<SimpleObj> > demoObjs;
|
||||
xmlDoc.objectsByType(&demoObjs);
|
||||
EXPECT_EQ(size_t(1), demoObjs.size());
|
||||
}
|
||||
|
||||
xmlDoc.deleteObjects();
|
||||
EXPECT_EQ(size_t(0), xmlDoc.objects().size());
|
||||
}
|
||||
|
||||
{
|
||||
caf::PdmDocument xmlDoc;
|
||||
|
||||
// Read file
|
||||
xmlDoc.fileName = "PdmTestFil.xml";
|
||||
xmlDoc.readFile();
|
||||
|
||||
// Test sample of that writing actually took place
|
||||
|
||||
std::vector<caf::PdmPointer<InheritedDemoObj> > ihDObjs;
|
||||
xmlDoc.objectsByType(&ihDObjs);
|
||||
EXPECT_EQ(size_t(2),ihDObjs.size() );
|
||||
ASSERT_EQ(size_t(4), ihDObjs[0]->m_simpleObjectsField.size());
|
||||
ASSERT_EQ(size_t(4), ihDObjs[0]->m_simpleObjectsField[1]->m_numbers().size());
|
||||
EXPECT_EQ(2.7, ihDObjs[0]->m_simpleObjectsField[1]->m_numbers()[3]);
|
||||
|
||||
EXPECT_EQ(QString("ÆØÅ Test text end"), ihDObjs[0]->m_textField());
|
||||
|
||||
// Write file
|
||||
QFile xmlFile("PdmTestFil2.xml");
|
||||
xmlFile.open(QIODevice::WriteOnly);
|
||||
xmlDoc.writeFile(&xmlFile);
|
||||
xmlFile.close();
|
||||
}
|
||||
|
||||
// Check that the files are identical
|
||||
{
|
||||
|
||||
QFile f1("PdmTestFil.xml");
|
||||
QFile f2("PdmTestFil2.xml");
|
||||
f1.open(QIODevice::ReadOnly);
|
||||
f2.open(QIODevice::ReadOnly);
|
||||
QByteArray ba1 = f1.readAll();
|
||||
QByteArray ba2 = f2.readAll();
|
||||
bool equal = ba1 == ba2;
|
||||
EXPECT_TRUE(equal);
|
||||
|
||||
// Then test how errors are handled
|
||||
{
|
||||
int pos = 0;
|
||||
int occurenceCount = 0;
|
||||
while (occurenceCount < 1)
|
||||
{
|
||||
pos = ba1.indexOf("<SimpleObj>", pos+1);
|
||||
occurenceCount++;
|
||||
}
|
||||
ba1.insert(pos+1, "Error");
|
||||
}
|
||||
|
||||
{
|
||||
int pos = 0;
|
||||
int occurenceCount = 0;
|
||||
while (occurenceCount < 1)
|
||||
{
|
||||
pos = ba1.indexOf("</SimpleObj>", pos +1);
|
||||
occurenceCount++;
|
||||
}
|
||||
ba1.insert(pos+2, "Error");
|
||||
}
|
||||
|
||||
{
|
||||
int pos = 0;
|
||||
int occurenceCount = 0;
|
||||
while (occurenceCount < 6) // Second position in a pointersfield
|
||||
{
|
||||
pos = ba1.indexOf("<SimpleObj>", pos +1);
|
||||
occurenceCount++;
|
||||
}
|
||||
ba1.insert(pos+1, "Error");
|
||||
}
|
||||
|
||||
{
|
||||
int pos = 0;
|
||||
int occurenceCount = 0;
|
||||
while (occurenceCount < 6) // Second position in a pointersfield
|
||||
{
|
||||
pos = ba1.indexOf("</SimpleObj>", pos +1);
|
||||
occurenceCount++;
|
||||
}
|
||||
ba1.insert(pos+2, "Error");
|
||||
}
|
||||
{
|
||||
int pos = ba1.indexOf("<BigNumber>");
|
||||
ba1.insert(pos+1, "Error");
|
||||
pos = ba1.indexOf("</BigNumber>");
|
||||
ba1.insert(pos+2, "Error");
|
||||
}
|
||||
{
|
||||
int pos = 0;
|
||||
int occurenceCount = 0;
|
||||
while (occurenceCount < 4)
|
||||
{
|
||||
pos = ba1.indexOf("<Numbers>", pos +1);
|
||||
occurenceCount++;
|
||||
}
|
||||
ba1.insert(pos+1, "Error");
|
||||
}
|
||||
|
||||
{
|
||||
int pos = 0;
|
||||
int occurenceCount = 0;
|
||||
while (occurenceCount < 4)
|
||||
{
|
||||
pos = ba1.indexOf("</Numbers>", pos +1);
|
||||
occurenceCount++;
|
||||
}
|
||||
ba1.insert(pos+2, "Error");
|
||||
}
|
||||
|
||||
// Write the edited document
|
||||
|
||||
QFile f3("PdmTestFilWithError.xml");
|
||||
f3.open(QIODevice::WriteOnly);
|
||||
f3.write(ba1);
|
||||
f3.close();
|
||||
|
||||
// Read the document containing errors
|
||||
caf::PdmDocument xmlErrorDoc;
|
||||
xmlErrorDoc.fileName = "PdmTestFilWithError.xml";
|
||||
xmlErrorDoc.readFile();
|
||||
|
||||
// Check the pointersfield
|
||||
std::vector<caf::PdmPointer<InheritedDemoObj> > ihDObjs;
|
||||
xmlErrorDoc.objectsByType(&ihDObjs);
|
||||
|
||||
EXPECT_EQ(size_t(2), ihDObjs.size() );
|
||||
ASSERT_EQ(size_t(3), ihDObjs[0]->m_simpleObjectsField.size());
|
||||
|
||||
// check single pointer field
|
||||
std::vector<caf::PdmPointer<DemoPdmObject> > demoObjs;
|
||||
xmlErrorDoc.objectsByType(&demoObjs);
|
||||
|
||||
EXPECT_EQ(size_t(4), demoObjs.size() );
|
||||
EXPECT_TRUE(demoObjs[0]->m_simpleObjPtrField == NULL );
|
||||
EXPECT_TRUE(demoObjs[0]->m_simpleObjPtrField2 != NULL );
|
||||
|
||||
// check single pointer field
|
||||
std::vector<caf::PdmPointer<SimpleObj> > simpleObjs;
|
||||
xmlErrorDoc.objectsByType(&simpleObjs);
|
||||
EXPECT_EQ(size_t(1), simpleObjs.size() );
|
||||
EXPECT_EQ(size_t(0), simpleObjs[0]->m_numbers().size());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Tests the features of PdmPointer
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST(BaseTest, PdmPointer)
|
||||
{
|
||||
caf::PdmDocument * d = new caf::PdmDocument;
|
||||
|
||||
{
|
||||
caf::PdmPointer<caf::PdmDocument> p;
|
||||
EXPECT_TRUE(p == NULL);
|
||||
}
|
||||
|
||||
{
|
||||
caf::PdmPointer<caf::PdmDocument> p(d);
|
||||
caf::PdmPointer<caf::PdmDocument> p2(p);
|
||||
|
||||
EXPECT_TRUE(p == d && p2 == d);
|
||||
EXPECT_TRUE(p.p() == d);
|
||||
EXPECT_TRUE((*p).uiName() == (*d).uiName());
|
||||
EXPECT_TRUE(p->uiName() == "File");
|
||||
p = 0;
|
||||
EXPECT_TRUE(p == NULL);
|
||||
EXPECT_TRUE(p.isNull());
|
||||
EXPECT_TRUE(p2 == d);
|
||||
p = p2;
|
||||
EXPECT_TRUE(p == d );
|
||||
delete d;
|
||||
EXPECT_TRUE(p.isNull() && p2.isNull());
|
||||
}
|
||||
|
||||
caf::PdmPointer<DemoPdmObject> p3(new DemoPdmObject());
|
||||
|
||||
delete p3;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Tests the PdmFactory
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST(BaseTest, PdmObjectFactory)
|
||||
{
|
||||
{
|
||||
SimpleObj* s = NULL;
|
||||
s = dynamic_cast<SimpleObj*> (caf::PdmObjectFactory::instance()->create("SimpleObj"));
|
||||
EXPECT_TRUE(s != NULL);
|
||||
}
|
||||
{
|
||||
DemoPdmObject* s = NULL;
|
||||
s = dynamic_cast<DemoPdmObject*> (caf::PdmObjectFactory::instance()->create("DemoPdmObject"));
|
||||
EXPECT_TRUE(s != NULL);
|
||||
delete s;
|
||||
}
|
||||
{
|
||||
InheritedDemoObj* s = NULL;
|
||||
s = dynamic_cast<InheritedDemoObj*> (caf::PdmObjectFactory::instance()->create("InheritedDemoObj"));
|
||||
EXPECT_TRUE(s != NULL);
|
||||
}
|
||||
|
||||
{
|
||||
caf::PdmDocument* s = NULL;
|
||||
s = dynamic_cast<caf::PdmDocument*> (caf::PdmObjectFactory::instance()->create("PdmDocument"));
|
||||
EXPECT_TRUE(s != NULL);
|
||||
}
|
||||
|
||||
{
|
||||
caf::PdmObjectGroup* s = NULL;
|
||||
s = dynamic_cast<caf::PdmObjectGroup*> (caf::PdmObjectFactory::instance()->create("PdmObjectGroup"));
|
||||
EXPECT_TRUE(s != NULL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Validate Xml keywords
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST(BaseTest, ValidXmlKeywords)
|
||||
{
|
||||
EXPECT_TRUE(caf::PdmObject::isValidXmlElementName("Valid_name"));
|
||||
|
||||
EXPECT_FALSE(caf::PdmObject::isValidXmlElementName("2Valid_name"));
|
||||
EXPECT_FALSE(caf::PdmObject::isValidXmlElementName(".Valid_name"));
|
||||
EXPECT_FALSE(caf::PdmObject::isValidXmlElementName("xml_Valid_name"));
|
||||
EXPECT_FALSE(caf::PdmObject::isValidXmlElementName("Valid_name_with_space "));
|
||||
}
|
||||
|
||||
TEST(BaseTest, PdmPointersFieldInsertVector)
|
||||
{
|
||||
InheritedDemoObj* ihd1 = new InheritedDemoObj;
|
||||
|
||||
SimpleObj* s1 = new SimpleObj;
|
||||
SimpleObj* s2 = new SimpleObj;
|
||||
SimpleObj* s3 = new SimpleObj;
|
||||
|
||||
caf::PdmObjectGroup pdmGroup;
|
||||
pdmGroup.addObject(s1);
|
||||
pdmGroup.addObject(s2);
|
||||
pdmGroup.addObject(s3);
|
||||
|
||||
std::vector<caf::PdmPointer<SimpleObj> > typedObjects;
|
||||
pdmGroup.objectsByType(&typedObjects);
|
||||
|
||||
ihd1->m_simpleObjectsField.insert(ihd1->m_simpleObjectsField.size(), typedObjects);
|
||||
EXPECT_EQ(size_t(3), ihd1->m_simpleObjectsField.size());
|
||||
|
||||
delete ihd1;
|
||||
}
|
||||
|
||||
TEST(BaseTest, PdmObjectGroupCopyOfTypedObjects)
|
||||
{
|
||||
SimpleObj* s1 = new SimpleObj;
|
||||
s1->m_position = 1000;
|
||||
s1->m_numbers.v().push_back(10);
|
||||
|
||||
SimpleObj* s2 = new SimpleObj;
|
||||
s2->m_position = 2000;
|
||||
|
||||
SimpleObj* s3 = new SimpleObj;
|
||||
s3->m_position = 3000;
|
||||
|
||||
InheritedDemoObj* ihd1 = new InheritedDemoObj;
|
||||
|
||||
caf::PdmObjectGroup og;
|
||||
og.objects.push_back(s1);
|
||||
og.objects.push_back(s2);
|
||||
og.objects.push_back(s3);
|
||||
og.objects.push_back(ihd1);
|
||||
|
||||
std::vector<caf::PdmPointer<SimpleObj> > simpleObjList;
|
||||
og.createCopyByType(&simpleObjList);
|
||||
EXPECT_EQ(size_t(3), simpleObjList.size());
|
||||
|
||||
std::vector<caf::PdmPointer<InheritedDemoObj> > inheritObjList;
|
||||
og.createCopyByType(&inheritObjList);
|
||||
EXPECT_EQ(size_t(1), inheritObjList.size());
|
||||
|
||||
og.deleteObjects();
|
||||
EXPECT_EQ(size_t(3), simpleObjList.size());
|
||||
EXPECT_EQ(size_t(1), inheritObjList.size());
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2013 Ceetron AS
|
||||
//
|
||||
// This library may be used under the terms of either the GNU General Public License or
|
||||
// the GNU Lesser General Public License as follows:
|
||||
//
|
||||
// GNU General Public License Usage
|
||||
// This library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
|
||||
// for more details.
|
||||
//
|
||||
// GNU Lesser General Public License Usage
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
int result = RUN_ALL_TESTS();
|
||||
|
||||
char text[5];
|
||||
std::cin.getline(text, 5);
|
||||
|
||||
return result;
|
||||
}
|
56
Fwk/AppFwk/cafTests/cafTestApplication/CMakeLists.txt
Normal file
@ -0,0 +1,56 @@
|
||||
cmake_minimum_required (VERSION 2.8)
|
||||
|
||||
project ( cafTestApplication )
|
||||
|
||||
# Qt MOC
|
||||
set ( QT_MOC_HEADERS
|
||||
MainWindow.h
|
||||
WidgetLayoutTest.h
|
||||
)
|
||||
|
||||
qt4_wrap_cpp( MOC_FILES_CPP
|
||||
${QT_MOC_HEADERS}
|
||||
)
|
||||
|
||||
# Resource file
|
||||
set( QRC_FILES
|
||||
textedit.qrc
|
||||
)
|
||||
|
||||
# Runs RCC on specified files
|
||||
qt4_add_resources( QRC_FILES_CPP
|
||||
${QRC_FILES}
|
||||
)
|
||||
|
||||
include_directories (
|
||||
${CMAKE_SOURCE_DIR}/cafProjectDataModel
|
||||
${CMAKE_SOURCE_DIR}/cafUserInterface
|
||||
)
|
||||
|
||||
# add the executable
|
||||
add_executable ( ${PROJECT_NAME}
|
||||
Main.cpp
|
||||
MainWindow.cpp
|
||||
WidgetLayoutTest.cpp
|
||||
${MOC_FILES_CPP}
|
||||
${QRC_FILES_CPP}
|
||||
)
|
||||
|
||||
target_link_libraries ( ${PROJECT_NAME}
|
||||
cafUserInterface
|
||||
cafProjectDataModel
|
||||
${QT_LIBRARIES}
|
||||
)
|
||||
|
||||
# Copy Qt Dlls
|
||||
if (MSVC)
|
||||
set (QTLIBLIST QtCore QtGui QtOpenGl)
|
||||
foreach (qtlib ${QTLIBLIST})
|
||||
|
||||
# Debug
|
||||
execute_process(COMMAND cmake -E copy_if_different ${QT_BINARY_DIR}/${qtlib}d4.dll ${CMAKE_CURRENT_BINARY_DIR}/Debug/${qtlib}d4.dll)
|
||||
|
||||
# Release
|
||||
execute_process(COMMAND cmake -E copy_if_different ${QT_BINARY_DIR}/${qtlib}4.dll ${CMAKE_CURRENT_BINARY_DIR}/Release/${qtlib}4.dll)
|
||||
endforeach( qtlib )
|
||||
endif(MSVC)
|
15
Fwk/AppFwk/cafTests/cafTestApplication/Main.cpp
Normal file
@ -0,0 +1,15 @@
|
||||
|
||||
#include "MainWindow.h"
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
MainWindow window;
|
||||
window.setWindowTitle("Ceetron Application Framework Test Application");
|
||||
window.show();
|
||||
|
||||
return app.exec();
|
||||
}
|
418
Fwk/AppFwk/cafTests/cafTestApplication/MainWindow.cpp
Normal file
@ -0,0 +1,418 @@
|
||||
|
||||
#include "MainWindow.h"
|
||||
#include "WidgetLayoutTest.h"
|
||||
|
||||
#include <QDockWidget>
|
||||
#include <QTreeView>
|
||||
#include <QAction>
|
||||
#include <QMenuBar>
|
||||
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmObject.h"
|
||||
#include "cafPdmDocument.h"
|
||||
#include "cafAppEnum.h"
|
||||
#include "cafUiTreeModelPdm.h"
|
||||
#include "cafPdmUiPropertyView.h"
|
||||
#include "cafPdmUiFilePathEditor.h"
|
||||
#include "cafPdmUiListEditor.h"
|
||||
#include "cafPdmUiTextEditor.h"
|
||||
|
||||
|
||||
|
||||
class DemoPdmObjectGroup: public caf::PdmObjectGroup
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
public:
|
||||
|
||||
DemoPdmObjectGroup()
|
||||
{
|
||||
CAF_PDM_InitObject("Demo Object Group", "", "This group object is a demo of the CAF framework", "This group object is a demo of the CAF framework")
|
||||
}
|
||||
};
|
||||
|
||||
CAF_PDM_SOURCE_INIT(DemoPdmObjectGroup, "DemoPdmObjectGroup");
|
||||
|
||||
class SmallDemoPdmObject: public caf::PdmObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
public:
|
||||
|
||||
SmallDemoPdmObject()
|
||||
{
|
||||
CAF_PDM_InitObject("Small Demo Object", ":/images/win/filenew.png", "This object is a demo of the CAF framework", "This object is a demo of the CAF framework");
|
||||
|
||||
CAF_PDM_InitField(&m_doubleField, "BigNumber", 0.0, "Big Number", "", "Enter a big number here", "This is a place you can enter a big real value if you want" );
|
||||
CAF_PDM_InitField(&m_intField, "IntNumber", 0, "Small Number", "", "Enter some small number here", "This is a place you can enter a small integer value if you want");
|
||||
CAF_PDM_InitField(&m_textField, "TextField", QString(""), "Text", "", "Text tooltip", "This is a place you can enter a small integer value if you want");
|
||||
}
|
||||
|
||||
caf::PdmField<double> m_doubleField;
|
||||
caf::PdmField<int> m_intField;
|
||||
caf::PdmField<QString> m_textField;
|
||||
};
|
||||
|
||||
CAF_PDM_SOURCE_INIT(SmallDemoPdmObject, "SmallDemoPdmObject");
|
||||
|
||||
|
||||
class SmallDemoPdmObjectA: public caf::PdmObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
public:
|
||||
|
||||
enum TestEnumType
|
||||
{
|
||||
T1, T2, T3
|
||||
};
|
||||
|
||||
|
||||
SmallDemoPdmObjectA()
|
||||
{
|
||||
CAF_PDM_InitObject("Small Demo Object A", "", "This object is a demo of the CAF framework", "This object is a demo of the CAF framework");
|
||||
|
||||
CAF_PDM_InitField(&m_doubleField, "BigNumber", 0.0, "Big Number", "", "Enter a big number here", "This is a place you can enter a big real value if you want");
|
||||
CAF_PDM_InitField(&m_intField, "IntNumber", 0, "Small Number", "", "Enter some small number here","This is a place you can enter a small integer value if you want");
|
||||
CAF_PDM_InitField(&m_textField, "TextField", QString(""), "Small Number", "", "Enter some small number here", "This is a place you can enter a small integer value if you want");
|
||||
CAF_PDM_InitField(&m_testEnumField, "TestEnumValue", caf::AppEnum<TestEnumType>(T1), "Small Number", "", "Enter some small number here", "This is a place you can enter a small integer value if you want");
|
||||
|
||||
m_testEnumField.setUiEditorTypeName(caf::PdmUiListEditor::uiEditorTypeName());
|
||||
}
|
||||
|
||||
caf::PdmField<double> m_doubleField;
|
||||
caf::PdmField<int> m_intField;
|
||||
caf::PdmField<QString> m_textField;
|
||||
caf::PdmField< caf::AppEnum<TestEnumType> > m_testEnumField;
|
||||
|
||||
};
|
||||
|
||||
CAF_PDM_SOURCE_INIT(SmallDemoPdmObjectA, "SmallDemoPdmObjectA");
|
||||
|
||||
namespace caf
|
||||
{
|
||||
template<>
|
||||
void AppEnum<SmallDemoPdmObjectA::TestEnumType>::setUp()
|
||||
{
|
||||
addItem(SmallDemoPdmObjectA::T1, "T1", "An A letter");
|
||||
addItem(SmallDemoPdmObjectA::T2, "T2", "A B letter");
|
||||
addItem(SmallDemoPdmObjectA::T3, "T3", "A B C letter");
|
||||
setDefault(SmallDemoPdmObjectA::T1);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Q_DECLARE_METATYPE(caf::AppEnum<SmallDemoPdmObjectA::TestEnumType>);
|
||||
|
||||
|
||||
|
||||
|
||||
class DemoPdmObject: public caf::PdmObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
public:
|
||||
|
||||
DemoPdmObject()
|
||||
{
|
||||
CAF_PDM_InitObject( "Demo Object", "", "This object is a demo of the CAF framework", "This object is a demo of the CAF framework");
|
||||
|
||||
CAF_PDM_InitField(&m_doubleField, "BigNumber", 0.0, "Big Number", "", "Enter a big number here", "This is a place you can enter a big real value if you want");
|
||||
CAF_PDM_InitField(&m_intField, "IntNumber", 0, "Small Number", "", "Enter some small number here", "This is a place you can enter a small integer value if you want" );
|
||||
CAF_PDM_InitField(&m_boolField, "BooleanValue", false, "Boolean:" , "", "Boolean:Enter some small number here", "Boolean:This is a place you can enter a small integer value if you want");
|
||||
CAF_PDM_InitField(&m_textField, "TextField", QString(""), "", "", "", "");
|
||||
CAF_PDM_InitField(&m_filePath, "FilePath", QString(""), "Filename", "", "", "");
|
||||
CAF_PDM_InitField(&m_longText, "LongText", QString("Test text"), "Long Text", "", "", "");
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&m_multiSelectList, "MultiSelect", "Selection List", "", "List" , "This is a multi selection list" );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&m_objectList, "ObjectList", "Objects list", "", "List" , "This is a list of PdmObjects" );
|
||||
|
||||
m_filePath.setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName());
|
||||
m_filePath.setUiLabelPosition(caf::PdmUiItemInfo::TOP);
|
||||
m_longText.setUiEditorTypeName(caf::PdmUiTextEditor::uiEditorTypeName());
|
||||
m_longText.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering)
|
||||
{
|
||||
uiOrdering.add(&m_boolField);
|
||||
caf::PdmUiGroup* group1 = uiOrdering.addNewGroup("Name1");
|
||||
group1->add(&m_doubleField);
|
||||
caf::PdmUiGroup* group2 = uiOrdering.addNewGroup("Name2");
|
||||
group2->add(&m_intField);
|
||||
caf::PdmUiGroup* group3 = group2->addNewGroup("Name3");
|
||||
group3->add(&m_textField);
|
||||
|
||||
//uiConfig->add(&f3);
|
||||
//uiConfig->forgetRemainingFields();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
virtual QList<caf::PdmOptionItemInfo> calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly)
|
||||
{
|
||||
QList<caf::PdmOptionItemInfo> options;
|
||||
if (&m_multiSelectList == fieldNeedingOptions)
|
||||
{
|
||||
|
||||
options.push_back(caf::PdmOptionItemInfo("Choice 1", "Choice1"));
|
||||
options.push_back(caf::PdmOptionItemInfo("Choice 2", "Choice2"));
|
||||
options.push_back(caf::PdmOptionItemInfo("Choice 3", "Choice3"));
|
||||
options.push_back(caf::PdmOptionItemInfo("Choice 4", "Choice4"));
|
||||
options.push_back(caf::PdmOptionItemInfo("Choice 5", "Choice5"));
|
||||
options.push_back(caf::PdmOptionItemInfo("Choice 6", "Choice6"));
|
||||
|
||||
}
|
||||
if (useOptionsOnly) *useOptionsOnly = true;
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
// Fields
|
||||
caf::PdmField<bool> m_boolField;
|
||||
caf::PdmField<double> m_doubleField;
|
||||
caf::PdmField<int> m_intField;
|
||||
caf::PdmField<QString> m_textField;
|
||||
|
||||
caf::PdmField<QString> m_filePath;
|
||||
|
||||
caf::PdmField<QString> m_longText;
|
||||
caf::PdmField<std::vector<QString> > m_multiSelectList;
|
||||
|
||||
|
||||
caf::PdmPointersField< caf::PdmObject* > m_objectList;
|
||||
};
|
||||
|
||||
CAF_PDM_SOURCE_INIT(DemoPdmObject, "DemoPdmObject");
|
||||
|
||||
|
||||
|
||||
MainWindow* MainWindow::sm_mainWindowInstance = NULL;
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
MainWindow::MainWindow()
|
||||
{
|
||||
m_treeView = NULL;
|
||||
m_treeModelPdm = NULL;
|
||||
|
||||
createActions();
|
||||
createDockPanels();
|
||||
|
||||
buildTestModel();
|
||||
setPdmRoot(m_testRoot);
|
||||
|
||||
sm_mainWindowInstance = this;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void MainWindow::createDockPanels()
|
||||
{
|
||||
{
|
||||
QDockWidget* dockWidget = new QDockWidget("Workspace", this);
|
||||
dockWidget->setObjectName("dockWidget");
|
||||
dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
|
||||
|
||||
m_treeView = new QTreeView(dockWidget);
|
||||
dockWidget->setWidget(m_treeView);
|
||||
|
||||
addDockWidget(Qt::LeftDockWidgetArea, dockWidget);
|
||||
}
|
||||
/*
|
||||
{
|
||||
QDockWidget* dockWidget = new QDockWidget("WidgetLayoutTest", this);
|
||||
dockWidget->setObjectName("dockWidget");
|
||||
dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
|
||||
|
||||
WidgetLayoutTest* widgetLayoutTest = new WidgetLayoutTest(dockWidget);
|
||||
dockWidget->setWidget(widgetLayoutTest);
|
||||
|
||||
addDockWidget(Qt::LeftDockWidgetArea, dockWidget);
|
||||
}
|
||||
*/
|
||||
|
||||
{
|
||||
QDockWidget* dockWidget = new QDockWidget("cafPropertyView", this);
|
||||
dockWidget->setObjectName("dockWidget");
|
||||
dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
|
||||
|
||||
m_pdmUiPropertyView = new caf::PdmUiPropertyView(dockWidget);
|
||||
dockWidget->setWidget(m_pdmUiPropertyView);
|
||||
|
||||
addDockWidget(Qt::LeftDockWidgetArea, dockWidget);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void MainWindow::buildTestModel()
|
||||
{
|
||||
m_testRoot = new DemoPdmObjectGroup;
|
||||
|
||||
DemoPdmObject* demoObject = new DemoPdmObject;
|
||||
m_testRoot->addObject(demoObject);
|
||||
|
||||
SmallDemoPdmObject* smallObj1 = new SmallDemoPdmObject;
|
||||
m_testRoot->addObject(smallObj1);
|
||||
|
||||
SmallDemoPdmObjectA* smallObj2 = new SmallDemoPdmObjectA;
|
||||
m_testRoot->addObject(smallObj2);
|
||||
|
||||
demoObject->m_objectList.push_back(new DemoPdmObject);
|
||||
demoObject->m_objectList.push_back(new SmallDemoPdmObjectA());
|
||||
demoObject->m_objectList.push_back(new SmallDemoPdmObject());
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void MainWindow::setPdmRoot(caf::PdmObject* pdmRoot)
|
||||
{
|
||||
caf::PdmUiTreeItem* treeItemRoot = caf::UiTreeItemBuilderPdm::buildViewItems(NULL, 0, pdmRoot);
|
||||
|
||||
if (!m_treeModelPdm)
|
||||
{
|
||||
m_treeModelPdm = new caf::UiTreeModelPdm(this);
|
||||
}
|
||||
|
||||
m_treeModelPdm->setTreeItemRoot(treeItemRoot);
|
||||
|
||||
assert(m_treeView);
|
||||
m_treeView->setModel(m_treeModelPdm);
|
||||
|
||||
if (treeItemRoot)
|
||||
{
|
||||
if (m_treeView->selectionModel())
|
||||
{
|
||||
connect(m_treeView->selectionModel(), SIGNAL(selectionChanged( const QItemSelection & , const QItemSelection & )), SLOT(slotSelectionChanged( const QItemSelection & , const QItemSelection & )));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void MainWindow::releaseTestData()
|
||||
{
|
||||
m_treeView->setModel(NULL);
|
||||
if (m_treeModelPdm)
|
||||
{
|
||||
delete m_treeModelPdm;
|
||||
}
|
||||
|
||||
if (m_testRoot)
|
||||
{
|
||||
m_testRoot->deleteObjects();
|
||||
delete m_testRoot;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
MainWindow* MainWindow::instance()
|
||||
{
|
||||
return sm_mainWindowInstance;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void MainWindow::createActions()
|
||||
{
|
||||
// Create actions
|
||||
QAction* editInsert = new QAction("&Insert", this);
|
||||
QAction* editRemove = new QAction("&Remove", this);
|
||||
QAction* editRemoveAll = new QAction("Remove all", this);
|
||||
|
||||
connect(editInsert, SIGNAL(triggered()), SLOT(slotInsert()));
|
||||
connect(editRemove, SIGNAL(triggered()), SLOT(slotRemove()));
|
||||
connect(editRemoveAll, SIGNAL(triggered()), SLOT(slotRemoveAll()));
|
||||
|
||||
|
||||
// Create menus
|
||||
QMenu* editMenu = menuBar()->addMenu("&Edit");
|
||||
editMenu->addAction(editInsert);
|
||||
editMenu->addAction(editRemove);
|
||||
editMenu->addAction(editRemoveAll);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void MainWindow::slotInsert()
|
||||
{
|
||||
QModelIndex index = m_treeView->selectionModel()->currentIndex();
|
||||
QAbstractItemModel *model = m_treeView->model();
|
||||
|
||||
if (!model->insertRow(0, index))
|
||||
return;
|
||||
|
||||
QModelIndex child = model->index(0, 0, index);
|
||||
|
||||
|
||||
// (
|
||||
// for (int column = 0; column < model->columnCount(index); ++column)
|
||||
// {
|
||||
// QModelIndex child = model->index(0, column, index);
|
||||
// model->setData(child, QVariant("[No data]"), Qt::EditRole);
|
||||
// if (!model->headerData(column, Qt::Horizontal).isValid())
|
||||
// model->setHeaderData(column, Qt::Horizontal, QVariant("[No header]"),
|
||||
// Qt::EditRole);
|
||||
// }
|
||||
// )
|
||||
|
||||
m_treeView->selectionModel()->setCurrentIndex(model->index(0, 0, index), QItemSelectionModel::ClearAndSelect);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void MainWindow::slotRemove()
|
||||
{
|
||||
QModelIndex index = m_treeView->selectionModel()->currentIndex();
|
||||
QAbstractItemModel *model = m_treeView->model();
|
||||
model->removeRow(index.row(), index.parent());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void MainWindow::slotRemoveAll()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void MainWindow::slotSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected )
|
||||
{
|
||||
if (selected.indexes().size() == 1)
|
||||
{
|
||||
QModelIndex mi = selected.indexes()[0];
|
||||
caf::PdmUiTreeItem* treeItem = m_treeModelPdm->getTreeItemFromIndex(mi);
|
||||
if (treeItem && treeItem->dataObject())
|
||||
{
|
||||
m_pdmUiPropertyView->showProperties(treeItem->dataObject());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pdmUiPropertyView->showProperties(NULL);
|
||||
}
|
||||
}
|
56
Fwk/AppFwk/cafTests/cafTestApplication/MainWindow.h
Normal file
@ -0,0 +1,56 @@
|
||||
#pragma once
|
||||
|
||||
#include <QtGui/QMainWindow>
|
||||
#include <QAbstractItemModel>
|
||||
#include <QItemSelection>
|
||||
|
||||
class DemoPdmObject;
|
||||
class QTreeView;
|
||||
|
||||
namespace caf
|
||||
{
|
||||
class PdmObjectGroup;
|
||||
class PdmObject;
|
||||
class UiTreeModelPdm;
|
||||
class PdmUiPropertyView;
|
||||
}
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MainWindow();
|
||||
~MainWindow();
|
||||
|
||||
static MainWindow* instance();
|
||||
void setPdmRoot(caf::PdmObject* pdmRoot);
|
||||
|
||||
private:
|
||||
void createActions();
|
||||
void createMenus();
|
||||
void createToolBars();
|
||||
void createDockPanels();
|
||||
|
||||
|
||||
void buildTestModel();
|
||||
void releaseTestData();
|
||||
|
||||
private slots:
|
||||
void slotInsert();
|
||||
void slotRemove();
|
||||
void slotRemoveAll();
|
||||
void slotSelectionChanged(const QItemSelection &, const QItemSelection & );
|
||||
|
||||
|
||||
private:
|
||||
static MainWindow* sm_mainWindowInstance;
|
||||
|
||||
private:
|
||||
QTreeView* m_treeView;
|
||||
caf::UiTreeModelPdm* m_treeModelPdm;
|
||||
caf::PdmUiPropertyView* m_pdmUiPropertyView;
|
||||
caf::PdmObjectGroup* m_testRoot;
|
||||
|
||||
};
|
||||
|
108
Fwk/AppFwk/cafTests/cafTestApplication/WidgetLayoutTest.cpp
Normal file
@ -0,0 +1,108 @@
|
||||
|
||||
#include "WidgetLayoutTest.h"
|
||||
|
||||
#include <QGridLayout>
|
||||
#include <QLineEdit>
|
||||
#include <QPushButton>
|
||||
#include <QGroupBox>
|
||||
#include <QLabel>
|
||||
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
WidgetLayoutTest::WidgetLayoutTest(QWidget* parent /*= 0*/, Qt::WindowFlags f /*= 0*/)
|
||||
: QWidget(parent, f)
|
||||
{
|
||||
QVBoxLayout* l = new QVBoxLayout;
|
||||
setLayout(l);
|
||||
|
||||
{
|
||||
QPushButton* b1 = new QPushButton("Original config", this);
|
||||
connect(b1, SIGNAL(clicked()), SLOT(setUpInitialConfiguration()));
|
||||
l->addWidget(b1);
|
||||
}
|
||||
|
||||
{
|
||||
QPushButton* b1 = new QPushButton("Config A", this);
|
||||
connect(b1, SIGNAL(clicked()), SLOT(setUpInitialConfigurationA()));
|
||||
l->addWidget(b1);
|
||||
}
|
||||
|
||||
{
|
||||
QPushButton* b1 = new QPushButton("Config B", this);
|
||||
connect(b1, SIGNAL(clicked()), SLOT(setUpInitialConfigurationB()));
|
||||
l->addWidget(b1);
|
||||
}
|
||||
|
||||
m_mainLayout = new QGridLayout();
|
||||
l->addLayout(m_mainLayout);
|
||||
|
||||
// Create widgets
|
||||
m_widget1 = new QLineEdit("1", this);
|
||||
m_widget2 = new QLineEdit("2", this);
|
||||
m_widget3 = new QLineEdit("3", this);
|
||||
m_widget4 = new QLineEdit("4", this);
|
||||
m_widget5 = new QLineEdit("5", this);
|
||||
|
||||
m_groupBoxA = new QGroupBox("Groupbox A", this);
|
||||
m_groupBoxALayout = new QGridLayout();
|
||||
m_groupBoxA->setLayout(m_groupBoxALayout);
|
||||
|
||||
m_groupBoxB = new QGroupBox("Groupbox B", this);
|
||||
m_groupBoxBLayout = new QGridLayout();
|
||||
m_groupBoxB->setLayout(m_groupBoxBLayout);
|
||||
|
||||
setUpInitialConfiguration();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
WidgetLayoutTest::~WidgetLayoutTest()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void WidgetLayoutTest::setUpInitialConfiguration()
|
||||
{
|
||||
m_mainLayout->addWidget(m_widget1);
|
||||
|
||||
m_mainLayout->addWidget(m_groupBoxA);
|
||||
|
||||
m_groupBoxALayout->addWidget(m_widget2, 0, 0);
|
||||
if (!m_widget3)
|
||||
{
|
||||
m_widget3 = new QLabel("Test label", this);
|
||||
}
|
||||
m_groupBoxALayout->addWidget(m_widget3, 1, 0);
|
||||
m_groupBoxALayout->addWidget(m_groupBoxB, 2, 0);
|
||||
|
||||
m_groupBoxBLayout->addWidget(m_widget4);
|
||||
|
||||
m_mainLayout->addWidget(m_widget5);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void WidgetLayoutTest::setUpInitialConfigurationA()
|
||||
{
|
||||
m_mainLayout->addWidget(m_widget2);
|
||||
|
||||
delete m_widget3;
|
||||
m_widget3 = NULL;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void WidgetLayoutTest::setUpInitialConfigurationB()
|
||||
{
|
||||
m_mainLayout->addWidget(m_widget4);
|
||||
}
|
41
Fwk/AppFwk/cafTests/cafTestApplication/WidgetLayoutTest.h
Normal file
@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include <QtGui/QWidget>
|
||||
|
||||
|
||||
class QGridLayout;
|
||||
class QGroupBox;
|
||||
|
||||
|
||||
|
||||
class WidgetLayoutTest : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
WidgetLayoutTest(QWidget* parent = 0, Qt::WindowFlags f = 0);
|
||||
~WidgetLayoutTest();
|
||||
|
||||
private:
|
||||
QGridLayout* m_mainLayout;
|
||||
|
||||
QGroupBox* m_groupBoxA;
|
||||
QGridLayout* m_groupBoxALayout;
|
||||
|
||||
QGroupBox* m_groupBoxB;
|
||||
QGridLayout* m_groupBoxBLayout;
|
||||
|
||||
QWidget* m_widget1;
|
||||
QWidget* m_widget2;
|
||||
QWidget* m_widget3;
|
||||
QWidget* m_widget4;
|
||||
QWidget* m_widget5;
|
||||
|
||||
private slots:
|
||||
void setUpInitialConfiguration();
|
||||
|
||||
void setUpInitialConfigurationA();
|
||||
void setUpInitialConfigurationB();
|
||||
|
||||
};
|
||||
|
BIN
Fwk/AppFwk/cafTests/cafTestApplication/images/logo32.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
Fwk/AppFwk/cafTests/cafTestApplication/images/mac/editcopy.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
Fwk/AppFwk/cafTests/cafTestApplication/images/mac/editcut.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
Fwk/AppFwk/cafTests/cafTestApplication/images/mac/editpaste.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
Fwk/AppFwk/cafTests/cafTestApplication/images/mac/editredo.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
Fwk/AppFwk/cafTests/cafTestApplication/images/mac/editundo.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
Fwk/AppFwk/cafTests/cafTestApplication/images/mac/exportpdf.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
Fwk/AppFwk/cafTests/cafTestApplication/images/mac/filenew.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
Fwk/AppFwk/cafTests/cafTestApplication/images/mac/fileopen.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
Fwk/AppFwk/cafTests/cafTestApplication/images/mac/fileprint.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
Fwk/AppFwk/cafTests/cafTestApplication/images/mac/filesave.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
Fwk/AppFwk/cafTests/cafTestApplication/images/mac/textbold.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
Fwk/AppFwk/cafTests/cafTestApplication/images/mac/textcenter.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
Fwk/AppFwk/cafTests/cafTestApplication/images/mac/textitalic.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.2 KiB |
BIN
Fwk/AppFwk/cafTests/cafTestApplication/images/mac/textleft.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
Fwk/AppFwk/cafTests/cafTestApplication/images/mac/textright.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
Fwk/AppFwk/cafTests/cafTestApplication/images/mac/textunder.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
Fwk/AppFwk/cafTests/cafTestApplication/images/mac/zoomin.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
Fwk/AppFwk/cafTests/cafTestApplication/images/mac/zoomout.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
Fwk/AppFwk/cafTests/cafTestApplication/images/win/editcopy.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
Fwk/AppFwk/cafTests/cafTestApplication/images/win/editcut.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
Fwk/AppFwk/cafTests/cafTestApplication/images/win/editpaste.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
Fwk/AppFwk/cafTests/cafTestApplication/images/win/editredo.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
Fwk/AppFwk/cafTests/cafTestApplication/images/win/editundo.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
Fwk/AppFwk/cafTests/cafTestApplication/images/win/exportpdf.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
Fwk/AppFwk/cafTests/cafTestApplication/images/win/filenew.png
Normal file
After Width: | Height: | Size: 768 B |
BIN
Fwk/AppFwk/cafTests/cafTestApplication/images/win/fileopen.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
Fwk/AppFwk/cafTests/cafTestApplication/images/win/fileprint.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
Fwk/AppFwk/cafTests/cafTestApplication/images/win/filesave.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
Fwk/AppFwk/cafTests/cafTestApplication/images/win/textbold.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
Fwk/AppFwk/cafTests/cafTestApplication/images/win/textcenter.png
Normal file
After Width: | Height: | Size: 627 B |
BIN
Fwk/AppFwk/cafTests/cafTestApplication/images/win/textitalic.png
Normal file
After Width: | Height: | Size: 829 B |
After Width: | Height: | Size: 695 B |
BIN
Fwk/AppFwk/cafTests/cafTestApplication/images/win/textleft.png
Normal file
After Width: | Height: | Size: 673 B |
BIN
Fwk/AppFwk/cafTests/cafTestApplication/images/win/textright.png
Normal file
After Width: | Height: | Size: 677 B |
BIN
Fwk/AppFwk/cafTests/cafTestApplication/images/win/textunder.png
Normal file
After Width: | Height: | Size: 971 B |
BIN
Fwk/AppFwk/cafTests/cafTestApplication/images/win/zoomin.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
Fwk/AppFwk/cafTests/cafTestApplication/images/win/zoomout.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
43
Fwk/AppFwk/cafTests/cafTestApplication/textedit.qrc
Normal file
@ -0,0 +1,43 @@
|
||||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource prefix="/">
|
||||
<file>images/logo32.png</file>
|
||||
<file>images/mac/editcopy.png</file>
|
||||
<file>images/mac/editcut.png</file>
|
||||
<file>images/mac/editpaste.png</file>
|
||||
<file>images/mac/editredo.png</file>
|
||||
<file>images/mac/editundo.png</file>
|
||||
<file>images/mac/exportpdf.png</file>
|
||||
<file>images/mac/filenew.png</file>
|
||||
<file>images/mac/fileopen.png</file>
|
||||
<file>images/mac/fileprint.png</file>
|
||||
<file>images/mac/filesave.png</file>
|
||||
<file>images/mac/textbold.png</file>
|
||||
<file>images/mac/textcenter.png</file>
|
||||
<file>images/mac/textitalic.png</file>
|
||||
<file>images/mac/textjustify.png</file>
|
||||
<file>images/mac/textleft.png</file>
|
||||
<file>images/mac/textright.png</file>
|
||||
<file>images/mac/textunder.png</file>
|
||||
<file>images/mac/zoomin.png</file>
|
||||
<file>images/mac/zoomout.png</file>
|
||||
<file>images/win/editcopy.png</file>
|
||||
<file>images/win/editcut.png</file>
|
||||
<file>images/win/editpaste.png</file>
|
||||
<file>images/win/editredo.png</file>
|
||||
<file>images/win/editundo.png</file>
|
||||
<file>images/win/exportpdf.png</file>
|
||||
<file>images/win/filenew.png</file>
|
||||
<file>images/win/fileopen.png</file>
|
||||
<file>images/win/fileprint.png</file>
|
||||
<file>images/win/filesave.png</file>
|
||||
<file>images/win/textbold.png</file>
|
||||
<file>images/win/textcenter.png</file>
|
||||
<file>images/win/textitalic.png</file>
|
||||
<file>images/win/textjustify.png</file>
|
||||
<file>images/win/textleft.png</file>
|
||||
<file>images/win/textright.png</file>
|
||||
<file>images/win/textunder.png</file>
|
||||
<file>images/win/zoomin.png</file>
|
||||
<file>images/win/zoomout.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
43
Fwk/AppFwk/cafTests/gtest/cvftestUtils.h
Normal file
@ -0,0 +1,43 @@
|
||||
|
||||
|
||||
|
||||
namespace cvftest {
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
class Utils
|
||||
{
|
||||
public:
|
||||
static cvf::String getTestDataDir(const cvf::String& unitTestFolder)
|
||||
{
|
||||
#ifdef WIN32
|
||||
std::string exe = std::string(testing::internal::GetArgvs()[0]);
|
||||
#else
|
||||
std::string dir = std::string(testing::internal::FilePath::GetCurrentDir().ToString());
|
||||
std::string exe = dir + std::string("/") + std::string(testing::internal::GetArgvs()[0]);
|
||||
#endif
|
||||
std::string testPath = exe.substr(0, exe.find(unitTestFolder.toStdString())) + std::string("TestData/");
|
||||
|
||||
return testPath;
|
||||
}
|
||||
|
||||
static cvf::String getGLSLDir(const cvf::String& unitTestFolder)
|
||||
{
|
||||
#ifdef WIN32
|
||||
std::string exe = std::string(testing::internal::GetArgvs()[0]);
|
||||
#else
|
||||
std::string dir = std::string(testing::internal::FilePath::GetCurrentDir().ToString());
|
||||
std::string exe = dir + std::string("/") + std::string(testing::internal::GetArgvs()[0]);
|
||||
#endif
|
||||
std::string glslPath = exe.substr(0, exe.find(unitTestFolder.toStdString())) + std::string("../LibRender/glsl/");
|
||||
|
||||
return glslPath;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
8510
Fwk/AppFwk/cafTests/gtest/gtest-all.cpp
Normal file
18007
Fwk/AppFwk/cafTests/gtest/gtest.h
Normal file
@ -159,6 +159,7 @@ LocatorPanWalkRotate::LocatorPanWalkRotate(Camera* camera)
|
||||
: m_camera(camera),
|
||||
m_operation(PAN),
|
||||
m_pos(0, 0, 0),
|
||||
m_rotQuat(0, 0, 0, 1),
|
||||
m_lastPosX(0),
|
||||
m_lastPosY(0)
|
||||
{
|
||||
@ -202,6 +203,24 @@ Vec3d LocatorPanWalkRotate::position() const
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void LocatorPanWalkRotate::setOrientation(const Mat3d& m)
|
||||
{
|
||||
m_rotQuat = Quatd::fromRotationMatrix(Mat4d(m));
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::Mat3d LocatorPanWalkRotate::orientation() const
|
||||
{
|
||||
return m_rotQuat.toMatrix3();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// The window coordinates are in OpenGL style coordinates, which means a right handed
|
||||
/// coordinate system with the origin in the lower left corner of the window.
|
||||
@ -221,31 +240,39 @@ bool LocatorPanWalkRotate::update(int x, int y)
|
||||
{
|
||||
CVF_ASSERT(m_camera.notNull());
|
||||
|
||||
if (x == m_lastPosX && y == m_lastPosY) return false;
|
||||
if (x == m_lastPosX && y == m_lastPosY)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const double vpPixSizeX = m_camera->viewport()->width();
|
||||
const double vpPixSizeY = m_camera->viewport()->height();
|
||||
if (vpPixSizeX <= 0 || vpPixSizeY <= 0) return false;
|
||||
// Need a non-zero viewport
|
||||
if (m_camera->viewport()->width() <= 0 ||
|
||||
m_camera->viewport()->height() <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Normalized movement in screen plane
|
||||
const double tx = (x - m_lastPosX)/vpPixSizeX;
|
||||
const double ty = (y - m_lastPosY)/vpPixSizeY;
|
||||
|
||||
Vec3d oldPos = m_pos;
|
||||
Quatd oldRotQuat = m_rotQuat;
|
||||
|
||||
if (m_operation == PAN)
|
||||
{
|
||||
updatePan(tx, ty);
|
||||
updatePan(x, y);
|
||||
}
|
||||
else if (m_operation == WALK)
|
||||
{
|
||||
updateWalk(ty);
|
||||
updateWalk(y);
|
||||
}
|
||||
else if (m_operation == ROTATE)
|
||||
{
|
||||
updateRotation(x, y);
|
||||
}
|
||||
|
||||
m_lastPosX = x;
|
||||
m_lastPosY = y;
|
||||
|
||||
if (m_pos == oldPos)
|
||||
if (m_pos == oldPos && m_rotQuat == oldRotQuat)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -259,10 +286,17 @@ bool LocatorPanWalkRotate::update(int x, int y)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void LocatorPanWalkRotate::updatePan(double tx, double ty)
|
||||
void LocatorPanWalkRotate::updatePan(int oglWinCoordX, int oglWinCoordY)
|
||||
{
|
||||
CVF_ASSERT(m_camera.notNull());
|
||||
|
||||
// Normalized movement in screen plane [0, 1]
|
||||
const double vpPixSizeX = m_camera->viewport()->width();
|
||||
const double vpPixSizeY = m_camera->viewport()->height();
|
||||
CVF_ASSERT(vpPixSizeX > 0 && vpPixSizeY > 0);
|
||||
const double tx = (oglWinCoordX - m_lastPosX)/vpPixSizeX;
|
||||
const double ty = (oglWinCoordY - m_lastPosY)/vpPixSizeY;
|
||||
|
||||
// Viewport size in world coordinates
|
||||
const double aspect = m_camera->aspectRatio();
|
||||
const double vpWorldSizeY = m_camera->frontPlaneFrustumHeight();
|
||||
@ -303,10 +337,15 @@ void LocatorPanWalkRotate::updatePan(double tx, double ty)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void LocatorPanWalkRotate::updateWalk(double ty)
|
||||
void LocatorPanWalkRotate::updateWalk(int oglWinCoordY)
|
||||
{
|
||||
CVF_ASSERT(m_camera.notNull());
|
||||
|
||||
// Normalized movement in screen plane [0, 1]
|
||||
const double vpPixSizeY = m_camera->viewport()->height();
|
||||
CVF_ASSERT(vpPixSizeY > 0);
|
||||
const double ty = (oglWinCoordY - m_lastPosY)/vpPixSizeY;
|
||||
|
||||
const double vpWorldSizeY = m_camera->frontPlaneFrustumHeight();
|
||||
const Vec3d camDir = m_camera->direction();
|
||||
|
||||
@ -337,5 +376,127 @@ void LocatorPanWalkRotate::updateWalk(double ty)
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void LocatorPanWalkRotate::updateRotation(int oglWinCoordX, int oglWinCoordY)
|
||||
{
|
||||
CVF_ASSERT(m_camera.notNull());
|
||||
|
||||
const double vpPixSizeX = m_camera->viewport()->width();
|
||||
const double vpPixSizeY = m_camera->viewport()->height();
|
||||
CVF_ASSERT(vpPixSizeX > 0 && vpPixSizeY > 0);
|
||||
|
||||
// Scale the new/last positions to the range [-1.0, 1.0]
|
||||
const double newPosX = 2.0*(oglWinCoordX/vpPixSizeX) - 1.0;
|
||||
const double newPosY = 2.0*((vpPixSizeY - oglWinCoordY)/vpPixSizeY) - 1.0;
|
||||
const double oldPosX = 2.0*(m_lastPosX/vpPixSizeX) - 1.0;
|
||||
const double oldPosY = 2.0*((vpPixSizeY - m_lastPosY)/vpPixSizeY) - 1.0;
|
||||
|
||||
// For now, use hard-coded value for trackball radius and sensitivity
|
||||
// Sensitivity could be exposed directly, but trackball rotation needs more consideration.
|
||||
// An idea would be for the user to be able to set an approximate size of the locator's visual representation in world coords,
|
||||
// and then we could estimate its current size relative to viewport, and then use that as trackball radius.
|
||||
// See trackballRotation() for some more info on trackballRadius (we've always used 0.8 as an approximation)
|
||||
const double trackballRadius = 0.8;
|
||||
const double rotateSensitivity = 1.0;
|
||||
Mat4d viewMat = m_camera->viewMatrix();
|
||||
Quatd incrementalRotationQuat = trackballRotation(oldPosX, -oldPosY, newPosX, -newPosY, viewMat, trackballRadius, rotateSensitivity);
|
||||
|
||||
// Update rotation quaternion
|
||||
Mat4d incRotationMatrix = incrementalRotationQuat.toMatrix4();
|
||||
incRotationMatrix.translatePostMultiply(-m_pos);
|
||||
incRotationMatrix.translatePreMultiply(m_pos);
|
||||
|
||||
Mat4d rotMat = m_rotQuat.toMatrix4();
|
||||
rotMat = incRotationMatrix*rotMat;
|
||||
|
||||
m_rotQuat = Quatd::fromRotationMatrix(rotMat);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Compute quaternion rotation
|
||||
///
|
||||
/// \param oldPosX x coordinate of the last position of the mouse, in the range [-1.0, 1.0]
|
||||
/// \param oldPosY y coordinate of the last position of the mouse, in the range [-1.0, 1.0]
|
||||
/// \param newPosX x coordinate of current position of the mouse, in the range [-1.0, 1.0]
|
||||
/// \param newPosY y coordinate of current position of the mouse, in the range [-1.0, 1.0]
|
||||
/// \param currViewMatrix Current transformation matrix. The inverse is used when calculating the rotation
|
||||
/// \param sensitivityFactor Mouse sensitivity factor
|
||||
///
|
||||
/// Simulate a track-ball. Project the points onto the virtual trackball, then figure out the axis
|
||||
/// of rotation. This is a deformed trackball-- is a trackball in the center, but is deformed into a
|
||||
/// hyperbolic sheet of rotation away from the center.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Quatd LocatorPanWalkRotate::trackballRotation(double oldPosX, double oldPosY, double newPosX, double newPosY, const Mat4d& currViewMatrix, double trackballRadius, double sensitivityFactor)
|
||||
{
|
||||
// This particular function was chosen after trying out several variations.
|
||||
// Implemented by Gavin Bell, lots of ideas from Thant Tessman and the August '88
|
||||
// issue of Siggraph's "Computer Graphics," pp. 121-129.
|
||||
|
||||
// This size should really be based on the distance from the center of rotation to the point on
|
||||
// the object underneath the mouse. That point would then track the mouse as closely as possible.
|
||||
//const double TRACKBALL_RADIUS = 0.8f;
|
||||
|
||||
// Clamp to valid range
|
||||
oldPosX = Math::clamp(oldPosX, -1.0, 1.0);
|
||||
oldPosY = Math::clamp(oldPosY, -1.0, 1.0);
|
||||
newPosX = Math::clamp(newPosX, -1.0, 1.0);
|
||||
newPosY = Math::clamp(newPosY, -1.0, 1.0);
|
||||
|
||||
// First, figure out z-coordinates for projection of P1 and P2 to deformed sphere
|
||||
Vec3d p1 = projectToSphere(trackballRadius, oldPosX, oldPosY);
|
||||
Vec3d p2 = projectToSphere(trackballRadius, newPosX, newPosY);
|
||||
|
||||
// Axis of rotation is the cross product of P1 and P2
|
||||
Vec3d a = p1 ^ p2;
|
||||
|
||||
// Figure out how much to rotate around that axis.
|
||||
Vec3d d = p1 - p2;
|
||||
double t = d.length()/(2.0*trackballRadius);
|
||||
|
||||
// Avoid problems with out-of-control values...
|
||||
t = Math::clamp(t, -1.0, 1.0);
|
||||
|
||||
double phi = 2.0*Math::asin(t);
|
||||
|
||||
// Scale by sensitivity factor
|
||||
phi *= sensitivityFactor;
|
||||
|
||||
// Use inverted matrix to find rotation axis
|
||||
Mat4d invMatr = currViewMatrix.getInverted();
|
||||
a.transformVector(invMatr);
|
||||
|
||||
// Get quaternion to be returned by pointer
|
||||
Quatd quat = Quatd::fromAxisAngle(a, phi);
|
||||
return quat;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Vec3d LocatorPanWalkRotate::projectToSphere(double radius, double posX, double posY)
|
||||
{
|
||||
double d = Math::sqrt(posX*posX + posY*posY);
|
||||
|
||||
if (d < radius*SQRT1_2_D)
|
||||
{
|
||||
// Inside sphere
|
||||
double projectedZ = Math::sqrt(radius*radius - d*d);
|
||||
|
||||
return Vec3d(posX, posY, projectedZ);
|
||||
}
|
||||
else
|
||||
{
|
||||
// On hyperbola
|
||||
double t = radius/SQRT2_D;
|
||||
double projectedZ = t*t/d;
|
||||
|
||||
return Vec3d(posX, posY, projectedZ);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace cvf
|
||||
|
||||
|
@ -38,6 +38,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "cvfPlane.h"
|
||||
#include "cvfQuat.h"
|
||||
|
||||
namespace cvf {
|
||||
|
||||
@ -97,8 +98,8 @@ public:
|
||||
enum Operation
|
||||
{
|
||||
PAN,
|
||||
WALK
|
||||
//ROTATE // TODO
|
||||
WALK,
|
||||
ROTATE
|
||||
};
|
||||
|
||||
public:
|
||||
@ -106,20 +107,29 @@ public:
|
||||
~LocatorPanWalkRotate();
|
||||
|
||||
void setOperation(Operation op);
|
||||
|
||||
void setPosition(const Vec3d& position);
|
||||
virtual Vec3d position() const;
|
||||
void setOrientation(const Mat3d& m);
|
||||
Mat3d orientation() const;
|
||||
|
||||
virtual void start(int x, int y);
|
||||
virtual bool update(int x, int y);
|
||||
|
||||
private:
|
||||
void updatePan(double tx, double ty);
|
||||
void updateWalk(double ty);
|
||||
void updatePan(int oglWinCoordX, int oglWinCoordY);
|
||||
void updateWalk(int oglWinCoordY);
|
||||
void updateRotation(int oglWinCoordX, int oglWinCoordY);
|
||||
|
||||
static Quatd trackballRotation(double oldPosX, double oldPosY, double newPosX, double newPosY, const Mat4d& currViewMatrix, double trackballRadius, double sensitivityFactor);
|
||||
static Vec3d projectToSphere(double radius, double posX, double posY);
|
||||
|
||||
private:
|
||||
ref<Camera> m_camera;
|
||||
Operation m_operation; // Default operation is PAN
|
||||
Vec3d m_pos;
|
||||
int m_lastPosX;
|
||||
Quatd m_rotQuat;
|
||||
int m_lastPosX; // Last position, window coords, origin lower left (OpenGL style)
|
||||
int m_lastPosY;
|
||||
};
|
||||
|
||||
|
@ -40,7 +40,6 @@
|
||||
#include "cvfCamera.h"
|
||||
#include "cvfViewport.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace cvf {
|
||||
@ -296,7 +295,7 @@ bool ManipulatorTrackball::zoom(int posX, int posY)
|
||||
Camera::ProjectionType projType = m_camera->projection();
|
||||
if (projType == Camera::PERSPECTIVE)
|
||||
{
|
||||
double fovY = 2*atan((newFrustumHeight/2)/nearPlane);
|
||||
double fovY = 2*Math::atan((newFrustumHeight/2)/nearPlane);
|
||||
if (fovY > 0)
|
||||
{
|
||||
m_camera->setProjectionAsPerspective(Math::toDegrees(fovY), nearPlane, farPlane);
|
||||
@ -407,7 +406,7 @@ Quatd ManipulatorTrackball::trackballRotation(double oldPosX, double oldPosY, do
|
||||
// Avoid problems with out-of-control values...
|
||||
t = Math::clamp(t, -1.0, 1.0);
|
||||
|
||||
double phi = 2.0*asin(t);
|
||||
double phi = 2.0*Math::asin(t);
|
||||
|
||||
// Scale by sensitivity factor
|
||||
phi *= sensitivityFactor;
|
||||
@ -437,12 +436,12 @@ Quatd ManipulatorTrackball::trackballRotation(double oldPosX, double oldPosY, do
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Vec3d ManipulatorTrackball::projectToSphere(double radius, double posX, double posY)
|
||||
{
|
||||
double d = sqrt(posX*posX + posY*posY);
|
||||
double d = Math::sqrt(posX*posX + posY*posY);
|
||||
|
||||
if (d < radius*SQRT1_2_D)
|
||||
{
|
||||
// Inside sphere
|
||||
double projectedZ = sqrt(radius*radius - d*d);
|
||||
double projectedZ = Math::sqrt(radius*radius - d*d);
|
||||
|
||||
return Vec3d(posX, posY, projectedZ);
|
||||
}
|
||||
|
@ -231,9 +231,20 @@ void Manipulators::onPaintEvent(PostEventAction* postEventAction)
|
||||
m_camera->applyOpenGL();
|
||||
|
||||
GeometryBuilderDrawableGeo builder;
|
||||
GeometryUtils::createBox(Vec3f(m_activeLocator->position()), 0.2f, 0.2f, 0.2f, &builder);
|
||||
|
||||
GeometryUtils::createBox(Vec3f::ZERO, 0.2f, 0.2f, 0.2f, &builder);
|
||||
ref<DrawableGeo> boxGeo = builder.drawableGeo();
|
||||
|
||||
Mat4d transform;
|
||||
|
||||
if (dynamic_cast<LocatorPanWalkRotate*>(m_activeLocator.p()))
|
||||
{
|
||||
LocatorPanWalkRotate* loc = dynamic_cast<LocatorPanWalkRotate*>(m_activeLocator.p());
|
||||
transform.setFromMatrix3(loc->orientation());
|
||||
}
|
||||
|
||||
transform.translatePreMultiply(m_activeLocator->position());
|
||||
|
||||
boxGeo->transform(transform);
|
||||
boxGeo->computeNormals();
|
||||
|
||||
RenderStateLighting_FF lighting;
|
||||
@ -262,15 +273,19 @@ void Manipulators::onMousePressEvent(MouseButton buttonPressed, MouseEvent* mous
|
||||
if (dynamic_cast<LocatorPanWalkRotate*>(m_activeLocator.p()))
|
||||
{
|
||||
LocatorPanWalkRotate* loc = dynamic_cast<LocatorPanWalkRotate*>(m_activeLocator.p());
|
||||
if (mouseEvent->buttons() == MiddleButton ||
|
||||
mouseEvent->buttons() == (LeftButton | RightButton))
|
||||
{
|
||||
loc->setOperation(LocatorPanWalkRotate::WALK);
|
||||
}
|
||||
else
|
||||
if (mouseEvent->buttons() == LeftButton)
|
||||
{
|
||||
loc->setOperation(LocatorPanWalkRotate::PAN);
|
||||
}
|
||||
else if (mouseEvent->buttons() == RightButton)
|
||||
{
|
||||
loc->setOperation(LocatorPanWalkRotate::ROTATE);
|
||||
}
|
||||
else if (mouseEvent->buttons() == MiddleButton ||
|
||||
mouseEvent->buttons() == (LeftButton | RightButton))
|
||||
{
|
||||
loc->setOperation(LocatorPanWalkRotate::WALK);
|
||||
}
|
||||
}
|
||||
|
||||
m_activeLocator->start(x, y);
|
||||
@ -293,9 +308,10 @@ void Manipulators::onMouseMoveEvent(MouseEvent* mouseEvent)
|
||||
{
|
||||
int x = mouseEvent->x();
|
||||
int y = mouseEvent->y();
|
||||
m_activeLocator->update(x, y);
|
||||
|
||||
mouseEvent->setRequestedAction(REDRAW);
|
||||
if (m_activeLocator->update(x, y))
|
||||
{
|
||||
mouseEvent->setRequestedAction(REDRAW);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|