1
1

Compare commits

...

94 Commits

Author SHA1 Message Date
b61abd4fe0 Merge from trunk r49908-r50219 2012-08-26 13:34:17 +00:00
43bb431548 Merge from trunk r49601-r49907 2012-08-14 23:37:19 +00:00
b8905ba0a6 Merge from trunk r49109-r49601 2012-08-06 09:59:24 +00:00
79f638791d Smoke + Cycles:
- Add Smoke Density node
- Make density available on GPU
- *TOTALLY* untested! Will most likely crash and you cannot render at the moment since "Volume BSDF" is missing (from blenderartists volume patch)

TODO:
- Fix "svm_node_smoke_density()", atm I have no idea how
2012-07-25 22:01:59 +00:00
0e31dcdf0d Reorganize some code + fix "use_volumetric" flag (true if smoke is used, false if not) 2012-07-25 16:44:43 +00:00
e9d3a54a40 Smoke + Cycles:
- Reorganize code a bit
- Use RNA function to directly copy density over

TODO:
- Fix scons to include blender_smoke.cpp
- "use_volume": Need flags to differ between "no density found" (can happen at frame 1) and "not a volume" (objects which have nothing to do with volume).
- Actually render something
- handle rendering (ignoring) of Smoke Domain + Flow
2012-07-24 23:49:50 +00:00
7f793b35b2 Start to work on Smoke + Cycles.
Goal is a proof of concept, then cleaning code up :-)
2012-07-23 09:18:32 +00:00
d0608872b7 Merge from trunk r48769-r49109 2012-07-21 23:23:56 +00:00
7f28ddfa8a Merge from turnk r48565-r48768 2012-07-09 20:49:03 +00:00
b8111fbea0 Disable Smoke velocity drawing for now 2012-07-08 20:00:48 +00:00
76837bd2b9 FIx compile error: Used tab instead of spaces 2012-07-08 18:10:53 +00:00
adbbcef63b Fix compile error with scons and without openmp 2012-07-08 16:18:15 +00:00
9868924573 Fix compile error when moving back to old Eigen version 2012-07-04 17:00:20 +00:00
6f55d7d9ae Recommit Eigen3 from trunk 2012-07-03 22:44:25 +00:00
cc68d19329 delete eigen 3 git version, substitute with trunk version later 2012-07-03 22:39:46 +00:00
5a472e64fb Merge from trunk r47744-r48564 2012-07-03 22:34:49 +00:00
72780227d0 Enable velocity drawing temporarely 2012-07-03 22:00:22 +00:00
8de4c368e4 Smoke Vorticity/turbulence: Porting the code idea from new turbulence paper. Moving obstacles will generate turbulence/vorticity now. This allows for a very natural reaction of smoke to obstacles.
Part of my Blender Smoke Development Phase III.
2012-07-03 21:49:01 +00:00
ec66cd4910 - Add CG helper for difficult setups
- Remove unsued code
2012-07-02 00:40:42 +00:00
bb5e072320 Remove old files from old Eigen version 2012-07-01 22:54:53 +00:00
13d14ea415 Update Eigen to latest git version 2012-07-01 22:52:18 +00:00
e99a990258 WIP comit: put preconditioners in a seperate function, use a loop macro 2012-07-01 22:39:14 +00:00
fc19e608a6 - Add old CG for reference 2012-06-18 19:49:47 +00:00
cd277bf7fe - Fix stopping criteria of CG 2012-06-18 18:12:18 +00:00
8397398c2a - Rewrite PCG: Still in testing phase 2012-06-18 17:55:38 +00:00
9885ac2096 - Fix exploding Smoke with moving obstacles: Enable "#if"-ed velocity constrain code 2012-06-18 16:07:07 +00:00
9fa604d301 - Fix scons error: Missing Eigen3 include folder 2012-06-15 12:29:33 +00:00
8317c02ec4 - Fix ompile error on linux
- Remove unused function declarations
2012-06-15 12:15:12 +00:00
8c55c2d65a - Fix crash on blend file loading
- Change bvh tree to 3 axes (should be faster for raytracing)
- Remove unused variables from DNA/code: ob_mat
2012-06-15 11:44:23 +00:00
c8441d334c - Remove unused code
- Set density to zero in obstacle cells
2012-06-14 21:56:45 +00:00
723982def2 - Fix moving obstacles: Velocity near the border of moving obstacles was set to zero.
- Fix drawing of obstacles: Did not draw all obstacle cells
2012-06-14 21:45:41 +00:00
8178792f9b - Fix disabled obstacles
- Fix drawing of obstacles_from_derivedmesh

Problems: Obstacles are not airtight yet
2012-06-14 18:04:26 +00:00
12c6ad7021 - First implementation of alternative obstacle handling, removing the needs of particle-points
- Enable debug obstacle drawing
2012-06-14 16:12:41 +00:00
1801983f36 Disable new CG for now 2012-06-13 10:12:55 +00:00
3ac5d889f6 Update Eigen3 to latest git revision. 2012-06-13 08:00:56 +00:00
22892f40ee Remove debug output 2012-06-12 11:35:46 +00:00
e4076d9590 Fix Eigen solver, can be enabled using define in fluid3d.h 2012-06-12 10:50:23 +00:00
440c7fa56d Fix Eigen3 CG algo 2012-06-12 09:58:38 +00:00
f74046ab65 WIP commit 2012-06-12 09:25:18 +00:00
35a92bacd0 Merge from trunk r47354-r47744 2012-06-11 15:19:12 +00:00
0ef73826e2 WIP commit 2012-06-07 08:43:21 +00:00
6489bb9593 Update Eigen3 to 3.1BETA 2012-06-06 22:18:58 +00:00
2c7363f5d5 Eigen3 CG does converge now, but only 1 round is a bit too fast, somethings still wrong 2012-06-05 11:24:48 +00:00
3894178175 Merge from trunk r47089-r47354 2012-06-02 21:33:31 +00:00
aa2addae16 Eigen3 "Kinda" working - still weird splitting up going on in 3dview 2012-05-31 10:54:27 +00:00
8309dc7159 Smoke: Fix messed up shadow display with OpenMP. This needs fixing. For now disable openmp for that function. Shadow calculation would be better raytraced on GPU or using shaders for the future.
Part of my Blender Smoke Development Phase III.
2012-05-28 14:29:20 +00:00
c0f8ad978c Default border to the same as within blender: No boundaries 2012-05-27 19:50:12 +00:00
15e6219fd3 Merge from trunk r46913-r47088 2012-05-27 19:31:35 +00:00
5e6fd995fe No changes, just commit before trunk merge 2012-05-27 18:48:35 +00:00
3319a32b98 Fix another typo, but still not working 2012-05-23 19:28:58 +00:00
3fbe6b3ac3 Fix matrix typos, still not working though 2012-05-23 16:10:43 +00:00
3242b8afea Use Eigen3 for pressure, but solving does give errors for now 2012-05-23 14:13:47 +00:00
8e3b221aaa Bring branch into sync with turnk again, some files were missed in past merges 2012-05-22 23:44:17 +00:00
483d4380e8 Merge from trunk r46815-r46913 2012-05-22 23:26:17 +00:00
cd9a3a3ca4 Enabled FFTW3 like it is already with scons 2012-05-22 23:19:45 +00:00
1a81eba430 - Delete one of many "bak" files
- Commit wip code, to help with merging changes from trunk
2012-05-22 23:06:57 +00:00
ac33410abb Update Eigen3 to latest 3.1 alpha2 to have support of sparse matrices 2012-05-22 23:04:18 +00:00
9f61ef1e89 Forgot to commit rest of smoke 2012-05-20 21:00:33 +00:00
c0e7c7acbf leftover from merge 2012-05-20 20:59:01 +00:00
5413fee77e Merge from trunk r46614-r46814 2012-05-20 19:35:49 +00:00
37ed2e4f46 - Use Smoke code from trunk again:
Unforeseen problems: The new code uses hidden arrays, file based functions. Nils himself describes the code as following in one of his new papers "Unuseable for rising smoke". What a bummer.
- New approach: Backport features as moving obstacles, preconditioned conjugate gradient solver, etc.

- This commit also contains the following code:
Better pressure and divergence calculation, idea taken from NVIDIA (graphic gems #3)
2012-05-20 17:25:45 +00:00
f3ed42fd4b a) Remove file dependencies, doing all in memory now
b) Fix crashes on Smoke init because of missing folder

Now we can start bringing back functionality.
2012-05-13 23:29:49 +00:00
d15ad02888 Merge r46323-r46613 from trunk 2012-05-13 18:59:10 +00:00
471d0fcc3f Use different solver names, uncomment some code. Note: Still needs scene and render folder to be created in the blender install folder, otherwise it crashes. Still only shows empty screen when using memory flags and not file flags 2012-05-07 18:39:52 +00:00
7c650602ca Fix merge error on my part -> Note: Never check the box "ignore spaces" 2012-05-05 20:59:24 +00:00
ecae41cc25 Fix another compile error caused by an accidental leftover file (scons only) 2012-05-05 19:36:00 +00:00
6a71020a92 Merge from trunk r46114-r46322 2012-05-05 19:15:33 +00:00
9824c244eb Branch only modification to enable openmp for windows 2012-05-05 18:48:58 +00:00
c292d72738 Fix compile error with gcc, enable scons compiling 2012-05-04 22:34:04 +00:00
f495c4db16 Fix compile warnings with gcc 2012-05-04 18:06:52 +00:00
208f09ce6b Fix compile error: Undefined reference zero 2012-05-04 17:59:25 +00:00
c4885add26 Fix memory leaks. 2012-05-04 11:23:01 +00:00
b482177b16 Add debug output:
Using memory flags ("new SolverObject") fails while loading the same grid from file works. Weird.
2012-05-04 00:16:16 +00:00
4231167c51 Fix errors + crashes on several occasion.
Known bug: _flags doesn't get used correctly in the init() of the "Smoke init B"
2012-05-03 22:47:00 +00:00
81967c83fd Backport NAN fix for wavelet noise from trunk 2012-05-02 20:53:06 +00:00
59e37352a5 Fix another crash caused by pointcache.
I commented some code to save me some startup time.
Remove the comments in FLUID_3D::init() to create your own setup files.
2012-05-01 23:09:26 +00:00
e1c9dc6892 Use smoke resolution provided by blender 2012-05-01 20:39:04 +00:00
fe883eac11 Revert last commit and fix "!" error in precompute loop 2012-05-01 11:25:28 +00:00
22db0708ba Halfway back using original source when seeing the bug 2012-05-01 11:21:59 +00:00
b84bd25655 First tests to bring back smoke display, but nothing displays yet for unknown reasons. 2012-04-30 23:19:56 +00:00
8ad9b4d497 a) Fix compile errors
b) Fix crashes when enabling smoke
c) Enabling, one timestep and deleting smoke works

Still no functionality.
2012-04-30 20:53:40 +00:00
103b601747 "Synthetic Turbulence using Artificial Boundary Layers" by Tobias Pfaff, Nils Thuerey et al.
http://graphics.ethz.ch/Downloads/Publications/Papers/2009/Pfa09/Pfa09.pdf

Remarks:
- Does only compile using cmake + windows. (Needs LAPACK)
- Smoke is completely broken at the time beeing.
- People can joing dev. For the moment I'm trying to move code from main.cpp to smoke.cpp
2012-04-30 12:50:58 +00:00
084582cf45 Merge trunk r46051-r46111 2012-04-30 12:44:43 +00:00
62de3d42b6 Update branch to match trunk smoke code 2012-04-30 12:08:17 +00:00
dfdf45b6f6 Remove debug print 2012-04-28 19:56:31 +00:00
85f56b9a10 Merge with trunk r46044-r46045
(pre trunk merge)
2012-04-28 19:52:31 +00:00
c50902b334 Merge with trunk r45960-r46043 2012-04-28 19:00:00 +00:00
81dbaf622f Merge r45854-r45959 from trunk 2012-04-25 08:29:42 +00:00
9d53b573c6 Merge with trunk revision45747 - revision45853 2012-04-22 19:20:22 +00:00
f10f33656f Fix collision objects: Crash when no domain was available. 2012-04-20 11:08:58 +00:00
04233010bd Fix compile error on linux. Reported by Mango team - thanks! 2012-04-19 12:21:44 +00:00
bda4be5f88 a) Merge trunk rev 45712 - 45744.
b) Correct accitental commit of elbeem file.
2012-04-18 13:13:54 +00:00
2316b93202 Smoke: Support moving collision objects.
Tested: Rigid movement.
Untested: Armature/etc (individual vertices) movement.

Sponsored by the Blender Development Fund.
2012-04-18 13:04:28 +00:00
1479698f09 Merge trunk rev 45664-45710 2012-04-17 12:14:16 +00:00
54 changed files with 2375 additions and 2256 deletions

View File

@@ -127,7 +127,7 @@ option(WITH_PYTHON_MODULE "Enable building as a python module which runs without
option(WITH_BUILDINFO "Include extra build details (only disable for development & faster builds)" ON)
option(WITH_IK_ITASC "Enable ITASC IK solver (only disable for development & for incompatible C++ compilers)" ON)
option(WITH_IK_SOLVER "Enable Legacy IK solver (only disable for development)" ON)
option(WITH_FFTW3 "Enable FFTW3 support (Used for smoke and audio effects)" OFF)
option(WITH_FFTW3 "Enable FFTW3 support (Used for smoke and audio effects)" ON)
option(WITH_BULLET "Enable Bullet (Physics Engine)" ON)
option(WITH_GAMEENGINE "Enable Game Engine" ON)
option(WITH_PLAYER "Build Player" OFF)
@@ -153,7 +153,7 @@ mark_as_advanced(WITH_AUDASPACE)
if((UNIX AND NOT APPLE) OR (MINGW))
set(PLATFORM_DEFAULT ON)
else()
set(PLATFORM_DEFAULT OFF)
set(PLATFORM_DEFAULT ON)
endif()
option(WITH_OPENMP "Enable OpenMP (has to be supported by the compiler)" ${PLATFORM_DEFAULT})
unset(PLATFORM_DEFAULT)
@@ -1685,9 +1685,9 @@ if(WITH_PYTHON)
if(NOT ${PYTHON_NUMPY_PATH} STREQUAL "")
if(NOT EXISTS "${PYTHON_NUMPY_PATH}/numpy")
message(WARNING "PYTHON_NUMPY_PATH is invalid, numpy not found in '${PYTHON_NUMPY_PATH}' "
"WITH_PYTHON_INSTALL_NUMPY option will be ignored when installing python")
"WITH_PYTHON_INSTALL_NUMPY option will be ignored when installing python")
set(WITH_PYTHON_INSTALL_NUMPY OFF)
endif()
endif()
# not set, so initialize
else()
string(REPLACE "." ";" _PY_VER_SPLIT "${PYTHON_VERSION}")
@@ -1717,11 +1717,11 @@ if(WITH_PYTHON)
set(WITH_PYTHON_INSTALL_NUMPY OFF)
else()
message(STATUS "numpy found at '${PYTHON_NUMPY_PATH}'")
endif()
endif()
unset(_PY_VER_SPLIT)
unset(_PY_VER_MAJOR)
endif()
endif()
endif()
endif()

View File

@@ -1,11 +1,11 @@
#ifndef EIGEN_ARRAY_MODULE_H
#define EIGEN_ARRAY_MODULE_H
// include Core first to handle Eigen2 support macros
#include "Core"
#ifndef EIGEN2_SUPPORT
#error The Eigen/Array header does no longer exist in Eigen3. All that functionality has moved to Eigen/Core.
#endif
#endif // EIGEN_ARRAY_MODULE_H
#ifndef EIGEN_ARRAY_MODULE_H
#define EIGEN_ARRAY_MODULE_H
// include Core first to handle Eigen2 support macros
#include "Core"
#ifndef EIGEN2_SUPPORT
#error The Eigen/Array header does no longer exist in Eigen3. All that functionality has moved to Eigen/Core.
#endif
#endif // EIGEN_ARRAY_MODULE_H

View File

@@ -1,33 +1,33 @@
#ifndef EIGEN_CHOLESKY_MODULE_H
#define EIGEN_CHOLESKY_MODULE_H
#include "Core"
#include "src/Core/util/DisableStupidWarnings.h"
namespace Eigen {
/** \defgroup Cholesky_Module Cholesky module
*
*
*
* This module provides two variants of the Cholesky decomposition for selfadjoint (hermitian) matrices.
* Those decompositions are accessible via the following MatrixBase methods:
* - MatrixBase::llt(),
* - MatrixBase::ldlt()
*
* \code
* #include <Eigen/Cholesky>
* \endcode
*/
#include "src/misc/Solve.h"
#include "src/Cholesky/LLT.h"
#include "src/Cholesky/LDLT.h"
} // namespace Eigen
#include "src/Core/util/ReenableStupidWarnings.h"
#endif // EIGEN_CHOLESKY_MODULE_H
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
#ifndef EIGEN_CHOLESKY_MODULE_H
#define EIGEN_CHOLESKY_MODULE_H
#include "Core"
#include "src/Core/util/DisableStupidWarnings.h"
namespace Eigen {
/** \defgroup Cholesky_Module Cholesky module
*
*
*
* This module provides two variants of the Cholesky decomposition for selfadjoint (hermitian) matrices.
* Those decompositions are accessible via the following MatrixBase methods:
* - MatrixBase::llt(),
* - MatrixBase::ldlt()
*
* \code
* #include <Eigen/Cholesky>
* \endcode
*/
#include "src/misc/Solve.h"
#include "src/Cholesky/LLT.h"
#include "src/Cholesky/LDLT.h"
} // namespace Eigen
#include "src/Core/util/ReenableStupidWarnings.h"
#endif // EIGEN_CHOLESKY_MODULE_H
/* vim: set filetype=cpp et sw=2 ts=2 ai: */

View File

@@ -1,360 +1,360 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
// Copyright (C) 2007-2011 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// Eigen 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 3 of the License, or (at your option) any later version.
//
// Alternatively, 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 2 of
// the License, or (at your option) any later version.
//
// Eigen 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 or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_CORE_H
#define EIGEN_CORE_H
// first thing Eigen does: stop the compiler from committing suicide
#include "src/Core/util/DisableStupidWarnings.h"
// then include this file where all our macros are defined. It's really important to do it first because
// it's where we do all the alignment settings (platform detection and honoring the user's will if he
// defined e.g. EIGEN_DONT_ALIGN) so it needs to be done before we do anything with vectorization.
#include "src/Core/util/Macros.h"
// if alignment is disabled, then disable vectorization. Note: EIGEN_ALIGN is the proper check, it takes into
// account both the user's will (EIGEN_DONT_ALIGN) and our own platform checks
#if !EIGEN_ALIGN
#ifndef EIGEN_DONT_VECTORIZE
#define EIGEN_DONT_VECTORIZE
#endif
#endif
#ifdef _MSC_VER
#include <malloc.h> // for _aligned_malloc -- need it regardless of whether vectorization is enabled
#if (_MSC_VER >= 1500) // 2008 or later
// Remember that usage of defined() in a #define is undefined by the standard.
// a user reported that in 64-bit mode, MSVC doesn't care to define _M_IX86_FP.
#if (defined(_M_IX86_FP) && (_M_IX86_FP >= 2)) || defined(_M_X64)
#define EIGEN_SSE2_ON_MSVC_2008_OR_LATER
#endif
#endif
#else
// Remember that usage of defined() in a #define is undefined by the standard
#if (defined __SSE2__) && ( (!defined __GNUC__) || EIGEN_GNUC_AT_LEAST(4,2) )
#define EIGEN_SSE2_ON_NON_MSVC_BUT_NOT_OLD_GCC
#endif
#endif
#ifndef EIGEN_DONT_VECTORIZE
#if defined (EIGEN_SSE2_ON_NON_MSVC_BUT_NOT_OLD_GCC) || defined(EIGEN_SSE2_ON_MSVC_2008_OR_LATER)
// Defines symbols for compile-time detection of which instructions are
// used.
// EIGEN_VECTORIZE_YY is defined if and only if the instruction set YY is used
#define EIGEN_VECTORIZE
#define EIGEN_VECTORIZE_SSE
#define EIGEN_VECTORIZE_SSE2
// Detect sse3/ssse3/sse4:
// gcc and icc defines __SSE3__, ...
// there is no way to know about this on msvc. You can define EIGEN_VECTORIZE_SSE* if you
// want to force the use of those instructions with msvc.
#ifdef __SSE3__
#define EIGEN_VECTORIZE_SSE3
#endif
#ifdef __SSSE3__
#define EIGEN_VECTORIZE_SSSE3
#endif
#ifdef __SSE4_1__
#define EIGEN_VECTORIZE_SSE4_1
#endif
#ifdef __SSE4_2__
#define EIGEN_VECTORIZE_SSE4_2
#endif
// include files
// This extern "C" works around a MINGW-w64 compilation issue
// https://sourceforge.net/tracker/index.php?func=detail&aid=3018394&group_id=202880&atid=983354
// In essence, intrin.h is included by windows.h and also declares intrinsics (just as emmintrin.h etc. below do).
// However, intrin.h uses an extern "C" declaration, and g++ thus complains of duplicate declarations
// with conflicting linkage. The linkage for intrinsics doesn't matter, but at that stage the compiler doesn't know;
// so, to avoid compile errors when windows.h is included after Eigen/Core, ensure intrinsics are extern "C" here too.
// notice that since these are C headers, the extern "C" is theoretically needed anyways.
extern "C" {
#include <emmintrin.h>
#include <xmmintrin.h>
#ifdef EIGEN_VECTORIZE_SSE3
#include <pmmintrin.h>
#endif
#ifdef EIGEN_VECTORIZE_SSSE3
#include <tmmintrin.h>
#endif
#ifdef EIGEN_VECTORIZE_SSE4_1
#include <smmintrin.h>
#endif
#ifdef EIGEN_VECTORIZE_SSE4_2
#include <nmmintrin.h>
#endif
} // end extern "C"
#elif defined __ALTIVEC__
#define EIGEN_VECTORIZE
#define EIGEN_VECTORIZE_ALTIVEC
#include <altivec.h>
// We need to #undef all these ugly tokens defined in <altivec.h>
// => use __vector instead of vector
#undef bool
#undef vector
#undef pixel
#elif defined __ARM_NEON__
#define EIGEN_VECTORIZE
#define EIGEN_VECTORIZE_NEON
#include <arm_neon.h>
#endif
#endif
#if (defined _OPENMP) && (!defined EIGEN_DONT_PARALLELIZE)
#define EIGEN_HAS_OPENMP
#endif
#ifdef EIGEN_HAS_OPENMP
#include <omp.h>
#endif
// MSVC for windows mobile does not have the errno.h file
#if !(defined(_MSC_VER) && defined(_WIN32_WCE))
#define EIGEN_HAS_ERRNO
#endif
#ifdef EIGEN_HAS_ERRNO
#include <cerrno>
#endif
#include <cstddef>
#include <cstdlib>
#include <cmath>
#include <complex>
#include <cassert>
#include <functional>
#include <iosfwd>
#include <cstring>
#include <string>
#include <limits>
#include <climits> // for CHAR_BIT
// for min/max:
#include <algorithm>
// for outputting debug info
#ifdef EIGEN_DEBUG_ASSIGN
#include <iostream>
#endif
// required for __cpuid, needs to be included after cmath
#if defined(_MSC_VER) && (defined(_M_IX86)||defined(_M_X64))
#include <intrin.h>
#endif
#if defined(_CPPUNWIND) || defined(__EXCEPTIONS)
#define EIGEN_EXCEPTIONS
#endif
#ifdef EIGEN_EXCEPTIONS
#include <new>
#endif
// defined in bits/termios.h
#undef B0
/** \brief Namespace containing all symbols from the %Eigen library. */
namespace Eigen {
inline static const char *SimdInstructionSetsInUse(void) {
#if defined(EIGEN_VECTORIZE_SSE4_2)
return "SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2";
#elif defined(EIGEN_VECTORIZE_SSE4_1)
return "SSE, SSE2, SSE3, SSSE3, SSE4.1";
#elif defined(EIGEN_VECTORIZE_SSSE3)
return "SSE, SSE2, SSE3, SSSE3";
#elif defined(EIGEN_VECTORIZE_SSE3)
return "SSE, SSE2, SSE3";
#elif defined(EIGEN_VECTORIZE_SSE2)
return "SSE, SSE2";
#elif defined(EIGEN_VECTORIZE_ALTIVEC)
return "AltiVec";
#elif defined(EIGEN_VECTORIZE_NEON)
return "ARM NEON";
#else
return "None";
#endif
}
#define STAGE10_FULL_EIGEN2_API 10
#define STAGE20_RESOLVE_API_CONFLICTS 20
#define STAGE30_FULL_EIGEN3_API 30
#define STAGE40_FULL_EIGEN3_STRICTNESS 40
#define STAGE99_NO_EIGEN2_SUPPORT 99
#if defined EIGEN2_SUPPORT_STAGE40_FULL_EIGEN3_STRICTNESS
#define EIGEN2_SUPPORT
#define EIGEN2_SUPPORT_STAGE STAGE40_FULL_EIGEN3_STRICTNESS
#elif defined EIGEN2_SUPPORT_STAGE30_FULL_EIGEN3_API
#define EIGEN2_SUPPORT
#define EIGEN2_SUPPORT_STAGE STAGE30_FULL_EIGEN3_API
#elif defined EIGEN2_SUPPORT_STAGE20_RESOLVE_API_CONFLICTS
#define EIGEN2_SUPPORT
#define EIGEN2_SUPPORT_STAGE STAGE20_RESOLVE_API_CONFLICTS
#elif defined EIGEN2_SUPPORT_STAGE10_FULL_EIGEN2_API
#define EIGEN2_SUPPORT
#define EIGEN2_SUPPORT_STAGE STAGE10_FULL_EIGEN2_API
#elif defined EIGEN2_SUPPORT
// default to stage 3, that's what it's always meant
#define EIGEN2_SUPPORT_STAGE30_FULL_EIGEN3_API
#define EIGEN2_SUPPORT_STAGE STAGE30_FULL_EIGEN3_API
#else
#define EIGEN2_SUPPORT_STAGE STAGE99_NO_EIGEN2_SUPPORT
#endif
#ifdef EIGEN2_SUPPORT
#undef minor
#endif
// we use size_t frequently and we'll never remember to prepend it with std:: everytime just to
// ensure QNX/QCC support
using std::size_t;
// gcc 4.6.0 wants std:: for ptrdiff_t
using std::ptrdiff_t;
/** \defgroup Core_Module Core module
* This is the main module of Eigen providing dense matrix and vector support
* (both fixed and dynamic size) with all the features corresponding to a BLAS library
* and much more...
*
* \code
* #include <Eigen/Core>
* \endcode
*/
#include "src/Core/util/Constants.h"
#include "src/Core/util/ForwardDeclarations.h"
#include "src/Core/util/Meta.h"
#include "src/Core/util/XprHelper.h"
#include "src/Core/util/StaticAssert.h"
#include "src/Core/util/Memory.h"
#include "src/Core/NumTraits.h"
#include "src/Core/MathFunctions.h"
#include "src/Core/GenericPacketMath.h"
#if defined EIGEN_VECTORIZE_SSE
#include "src/Core/arch/SSE/PacketMath.h"
#include "src/Core/arch/SSE/MathFunctions.h"
#include "src/Core/arch/SSE/Complex.h"
#elif defined EIGEN_VECTORIZE_ALTIVEC
#include "src/Core/arch/AltiVec/PacketMath.h"
#include "src/Core/arch/AltiVec/Complex.h"
#elif defined EIGEN_VECTORIZE_NEON
#include "src/Core/arch/NEON/PacketMath.h"
#include "src/Core/arch/NEON/Complex.h"
#endif
#include "src/Core/arch/Default/Settings.h"
#include "src/Core/Functors.h"
#include "src/Core/DenseCoeffsBase.h"
#include "src/Core/DenseBase.h"
#include "src/Core/MatrixBase.h"
#include "src/Core/EigenBase.h"
#ifndef EIGEN_PARSED_BY_DOXYGEN // work around Doxygen bug triggered by Assign.h r814874
// at least confirmed with Doxygen 1.5.5 and 1.5.6
#include "src/Core/Assign.h"
#endif
#include "src/Core/util/BlasUtil.h"
#include "src/Core/DenseStorage.h"
#include "src/Core/NestByValue.h"
#include "src/Core/ForceAlignedAccess.h"
#include "src/Core/ReturnByValue.h"
#include "src/Core/NoAlias.h"
#include "src/Core/PlainObjectBase.h"
#include "src/Core/Matrix.h"
#include "src/Core/Array.h"
#include "src/Core/CwiseBinaryOp.h"
#include "src/Core/CwiseUnaryOp.h"
#include "src/Core/CwiseNullaryOp.h"
#include "src/Core/CwiseUnaryView.h"
#include "src/Core/SelfCwiseBinaryOp.h"
#include "src/Core/Dot.h"
#include "src/Core/StableNorm.h"
#include "src/Core/MapBase.h"
#include "src/Core/Stride.h"
#include "src/Core/Map.h"
#include "src/Core/Block.h"
#include "src/Core/VectorBlock.h"
#include "src/Core/Transpose.h"
#include "src/Core/DiagonalMatrix.h"
#include "src/Core/Diagonal.h"
#include "src/Core/DiagonalProduct.h"
#include "src/Core/PermutationMatrix.h"
#include "src/Core/Transpositions.h"
#include "src/Core/Redux.h"
#include "src/Core/Visitor.h"
#include "src/Core/Fuzzy.h"
#include "src/Core/IO.h"
#include "src/Core/Swap.h"
#include "src/Core/CommaInitializer.h"
#include "src/Core/Flagged.h"
#include "src/Core/ProductBase.h"
#include "src/Core/Product.h"
#include "src/Core/TriangularMatrix.h"
#include "src/Core/SelfAdjointView.h"
#include "src/Core/SolveTriangular.h"
#include "src/Core/products/Parallelizer.h"
#include "src/Core/products/CoeffBasedProduct.h"
#include "src/Core/products/GeneralBlockPanelKernel.h"
#include "src/Core/products/GeneralMatrixVector.h"
#include "src/Core/products/GeneralMatrixMatrix.h"
#include "src/Core/products/GeneralMatrixMatrixTriangular.h"
#include "src/Core/products/SelfadjointMatrixVector.h"
#include "src/Core/products/SelfadjointMatrixMatrix.h"
#include "src/Core/products/SelfadjointProduct.h"
#include "src/Core/products/SelfadjointRank2Update.h"
#include "src/Core/products/TriangularMatrixVector.h"
#include "src/Core/products/TriangularMatrixMatrix.h"
#include "src/Core/products/TriangularSolverMatrix.h"
#include "src/Core/products/TriangularSolverVector.h"
#include "src/Core/BandMatrix.h"
#include "src/Core/BooleanRedux.h"
#include "src/Core/Select.h"
#include "src/Core/VectorwiseOp.h"
#include "src/Core/Random.h"
#include "src/Core/Replicate.h"
#include "src/Core/Reverse.h"
#include "src/Core/ArrayBase.h"
#include "src/Core/ArrayWrapper.h"
} // namespace Eigen
#include "src/Core/GlobalFunctions.h"
#include "src/Core/util/ReenableStupidWarnings.h"
#ifdef EIGEN2_SUPPORT
#include "Eigen2Support"
#endif
#endif // EIGEN_CORE_H
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
// Copyright (C) 2007-2011 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// Eigen 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 3 of the License, or (at your option) any later version.
//
// Alternatively, 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 2 of
// the License, or (at your option) any later version.
//
// Eigen 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 or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_CORE_H
#define EIGEN_CORE_H
// first thing Eigen does: stop the compiler from committing suicide
#include "src/Core/util/DisableStupidWarnings.h"
// then include this file where all our macros are defined. It's really important to do it first because
// it's where we do all the alignment settings (platform detection and honoring the user's will if he
// defined e.g. EIGEN_DONT_ALIGN) so it needs to be done before we do anything with vectorization.
#include "src/Core/util/Macros.h"
// if alignment is disabled, then disable vectorization. Note: EIGEN_ALIGN is the proper check, it takes into
// account both the user's will (EIGEN_DONT_ALIGN) and our own platform checks
#if !EIGEN_ALIGN
#ifndef EIGEN_DONT_VECTORIZE
#define EIGEN_DONT_VECTORIZE
#endif
#endif
#ifdef _MSC_VER
#include <malloc.h> // for _aligned_malloc -- need it regardless of whether vectorization is enabled
#if (_MSC_VER >= 1500) // 2008 or later
// Remember that usage of defined() in a #define is undefined by the standard.
// a user reported that in 64-bit mode, MSVC doesn't care to define _M_IX86_FP.
#if (defined(_M_IX86_FP) && (_M_IX86_FP >= 2)) || defined(_M_X64)
#define EIGEN_SSE2_ON_MSVC_2008_OR_LATER
#endif
#endif
#else
// Remember that usage of defined() in a #define is undefined by the standard
#if (defined __SSE2__) && ( (!defined __GNUC__) || EIGEN_GNUC_AT_LEAST(4,2) )
#define EIGEN_SSE2_ON_NON_MSVC_BUT_NOT_OLD_GCC
#endif
#endif
#ifndef EIGEN_DONT_VECTORIZE
#if defined (EIGEN_SSE2_ON_NON_MSVC_BUT_NOT_OLD_GCC) || defined(EIGEN_SSE2_ON_MSVC_2008_OR_LATER)
// Defines symbols for compile-time detection of which instructions are
// used.
// EIGEN_VECTORIZE_YY is defined if and only if the instruction set YY is used
#define EIGEN_VECTORIZE
#define EIGEN_VECTORIZE_SSE
#define EIGEN_VECTORIZE_SSE2
// Detect sse3/ssse3/sse4:
// gcc and icc defines __SSE3__, ...
// there is no way to know about this on msvc. You can define EIGEN_VECTORIZE_SSE* if you
// want to force the use of those instructions with msvc.
#ifdef __SSE3__
#define EIGEN_VECTORIZE_SSE3
#endif
#ifdef __SSSE3__
#define EIGEN_VECTORIZE_SSSE3
#endif
#ifdef __SSE4_1__
#define EIGEN_VECTORIZE_SSE4_1
#endif
#ifdef __SSE4_2__
#define EIGEN_VECTORIZE_SSE4_2
#endif
// include files
// This extern "C" works around a MINGW-w64 compilation issue
// https://sourceforge.net/tracker/index.php?func=detail&aid=3018394&group_id=202880&atid=983354
// In essence, intrin.h is included by windows.h and also declares intrinsics (just as emmintrin.h etc. below do).
// However, intrin.h uses an extern "C" declaration, and g++ thus complains of duplicate declarations
// with conflicting linkage. The linkage for intrinsics doesn't matter, but at that stage the compiler doesn't know;
// so, to avoid compile errors when windows.h is included after Eigen/Core, ensure intrinsics are extern "C" here too.
// notice that since these are C headers, the extern "C" is theoretically needed anyways.
extern "C" {
#include <emmintrin.h>
#include <xmmintrin.h>
#ifdef EIGEN_VECTORIZE_SSE3
#include <pmmintrin.h>
#endif
#ifdef EIGEN_VECTORIZE_SSSE3
#include <tmmintrin.h>
#endif
#ifdef EIGEN_VECTORIZE_SSE4_1
#include <smmintrin.h>
#endif
#ifdef EIGEN_VECTORIZE_SSE4_2
#include <nmmintrin.h>
#endif
} // end extern "C"
#elif defined __ALTIVEC__
#define EIGEN_VECTORIZE
#define EIGEN_VECTORIZE_ALTIVEC
#include <altivec.h>
// We need to #undef all these ugly tokens defined in <altivec.h>
// => use __vector instead of vector
#undef bool
#undef vector
#undef pixel
#elif defined __ARM_NEON__
#define EIGEN_VECTORIZE
#define EIGEN_VECTORIZE_NEON
#include <arm_neon.h>
#endif
#endif
#if (defined _OPENMP) && (!defined EIGEN_DONT_PARALLELIZE)
#define EIGEN_HAS_OPENMP
#endif
#ifdef EIGEN_HAS_OPENMP
#include <omp.h>
#endif
// MSVC for windows mobile does not have the errno.h file
#if !(defined(_MSC_VER) && defined(_WIN32_WCE))
#define EIGEN_HAS_ERRNO
#endif
#ifdef EIGEN_HAS_ERRNO
#include <cerrno>
#endif
#include <cstddef>
#include <cstdlib>
#include <cmath>
#include <complex>
#include <cassert>
#include <functional>
#include <iosfwd>
#include <cstring>
#include <string>
#include <limits>
#include <climits> // for CHAR_BIT
// for min/max:
#include <algorithm>
// for outputting debug info
#ifdef EIGEN_DEBUG_ASSIGN
#include <iostream>
#endif
// required for __cpuid, needs to be included after cmath
#if defined(_MSC_VER) && (defined(_M_IX86)||defined(_M_X64))
#include <intrin.h>
#endif
#if defined(_CPPUNWIND) || defined(__EXCEPTIONS)
#define EIGEN_EXCEPTIONS
#endif
#ifdef EIGEN_EXCEPTIONS
#include <new>
#endif
// defined in bits/termios.h
#undef B0
/** \brief Namespace containing all symbols from the %Eigen library. */
namespace Eigen {
inline static const char *SimdInstructionSetsInUse(void) {
#if defined(EIGEN_VECTORIZE_SSE4_2)
return "SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2";
#elif defined(EIGEN_VECTORIZE_SSE4_1)
return "SSE, SSE2, SSE3, SSSE3, SSE4.1";
#elif defined(EIGEN_VECTORIZE_SSSE3)
return "SSE, SSE2, SSE3, SSSE3";
#elif defined(EIGEN_VECTORIZE_SSE3)
return "SSE, SSE2, SSE3";
#elif defined(EIGEN_VECTORIZE_SSE2)
return "SSE, SSE2";
#elif defined(EIGEN_VECTORIZE_ALTIVEC)
return "AltiVec";
#elif defined(EIGEN_VECTORIZE_NEON)
return "ARM NEON";
#else
return "None";
#endif
}
#define STAGE10_FULL_EIGEN2_API 10
#define STAGE20_RESOLVE_API_CONFLICTS 20
#define STAGE30_FULL_EIGEN3_API 30
#define STAGE40_FULL_EIGEN3_STRICTNESS 40
#define STAGE99_NO_EIGEN2_SUPPORT 99
#if defined EIGEN2_SUPPORT_STAGE40_FULL_EIGEN3_STRICTNESS
#define EIGEN2_SUPPORT
#define EIGEN2_SUPPORT_STAGE STAGE40_FULL_EIGEN3_STRICTNESS
#elif defined EIGEN2_SUPPORT_STAGE30_FULL_EIGEN3_API
#define EIGEN2_SUPPORT
#define EIGEN2_SUPPORT_STAGE STAGE30_FULL_EIGEN3_API
#elif defined EIGEN2_SUPPORT_STAGE20_RESOLVE_API_CONFLICTS
#define EIGEN2_SUPPORT
#define EIGEN2_SUPPORT_STAGE STAGE20_RESOLVE_API_CONFLICTS
#elif defined EIGEN2_SUPPORT_STAGE10_FULL_EIGEN2_API
#define EIGEN2_SUPPORT
#define EIGEN2_SUPPORT_STAGE STAGE10_FULL_EIGEN2_API
#elif defined EIGEN2_SUPPORT
// default to stage 3, that's what it's always meant
#define EIGEN2_SUPPORT_STAGE30_FULL_EIGEN3_API
#define EIGEN2_SUPPORT_STAGE STAGE30_FULL_EIGEN3_API
#else
#define EIGEN2_SUPPORT_STAGE STAGE99_NO_EIGEN2_SUPPORT
#endif
#ifdef EIGEN2_SUPPORT
#undef minor
#endif
// we use size_t frequently and we'll never remember to prepend it with std:: everytime just to
// ensure QNX/QCC support
using std::size_t;
// gcc 4.6.0 wants std:: for ptrdiff_t
using std::ptrdiff_t;
/** \defgroup Core_Module Core module
* This is the main module of Eigen providing dense matrix and vector support
* (both fixed and dynamic size) with all the features corresponding to a BLAS library
* and much more...
*
* \code
* #include <Eigen/Core>
* \endcode
*/
#include "src/Core/util/Constants.h"
#include "src/Core/util/ForwardDeclarations.h"
#include "src/Core/util/Meta.h"
#include "src/Core/util/XprHelper.h"
#include "src/Core/util/StaticAssert.h"
#include "src/Core/util/Memory.h"
#include "src/Core/NumTraits.h"
#include "src/Core/MathFunctions.h"
#include "src/Core/GenericPacketMath.h"
#if defined EIGEN_VECTORIZE_SSE
#include "src/Core/arch/SSE/PacketMath.h"
#include "src/Core/arch/SSE/MathFunctions.h"
#include "src/Core/arch/SSE/Complex.h"
#elif defined EIGEN_VECTORIZE_ALTIVEC
#include "src/Core/arch/AltiVec/PacketMath.h"
#include "src/Core/arch/AltiVec/Complex.h"
#elif defined EIGEN_VECTORIZE_NEON
#include "src/Core/arch/NEON/PacketMath.h"
#include "src/Core/arch/NEON/Complex.h"
#endif
#include "src/Core/arch/Default/Settings.h"
#include "src/Core/Functors.h"
#include "src/Core/DenseCoeffsBase.h"
#include "src/Core/DenseBase.h"
#include "src/Core/MatrixBase.h"
#include "src/Core/EigenBase.h"
#ifndef EIGEN_PARSED_BY_DOXYGEN // work around Doxygen bug triggered by Assign.h r814874
// at least confirmed with Doxygen 1.5.5 and 1.5.6
#include "src/Core/Assign.h"
#endif
#include "src/Core/util/BlasUtil.h"
#include "src/Core/DenseStorage.h"
#include "src/Core/NestByValue.h"
#include "src/Core/ForceAlignedAccess.h"
#include "src/Core/ReturnByValue.h"
#include "src/Core/NoAlias.h"
#include "src/Core/PlainObjectBase.h"
#include "src/Core/Matrix.h"
#include "src/Core/Array.h"
#include "src/Core/CwiseBinaryOp.h"
#include "src/Core/CwiseUnaryOp.h"
#include "src/Core/CwiseNullaryOp.h"
#include "src/Core/CwiseUnaryView.h"
#include "src/Core/SelfCwiseBinaryOp.h"
#include "src/Core/Dot.h"
#include "src/Core/StableNorm.h"
#include "src/Core/MapBase.h"
#include "src/Core/Stride.h"
#include "src/Core/Map.h"
#include "src/Core/Block.h"
#include "src/Core/VectorBlock.h"
#include "src/Core/Transpose.h"
#include "src/Core/DiagonalMatrix.h"
#include "src/Core/Diagonal.h"
#include "src/Core/DiagonalProduct.h"
#include "src/Core/PermutationMatrix.h"
#include "src/Core/Transpositions.h"
#include "src/Core/Redux.h"
#include "src/Core/Visitor.h"
#include "src/Core/Fuzzy.h"
#include "src/Core/IO.h"
#include "src/Core/Swap.h"
#include "src/Core/CommaInitializer.h"
#include "src/Core/Flagged.h"
#include "src/Core/ProductBase.h"
#include "src/Core/Product.h"
#include "src/Core/TriangularMatrix.h"
#include "src/Core/SelfAdjointView.h"
#include "src/Core/SolveTriangular.h"
#include "src/Core/products/Parallelizer.h"
#include "src/Core/products/CoeffBasedProduct.h"
#include "src/Core/products/GeneralBlockPanelKernel.h"
#include "src/Core/products/GeneralMatrixVector.h"
#include "src/Core/products/GeneralMatrixMatrix.h"
#include "src/Core/products/GeneralMatrixMatrixTriangular.h"
#include "src/Core/products/SelfadjointMatrixVector.h"
#include "src/Core/products/SelfadjointMatrixMatrix.h"
#include "src/Core/products/SelfadjointProduct.h"
#include "src/Core/products/SelfadjointRank2Update.h"
#include "src/Core/products/TriangularMatrixVector.h"
#include "src/Core/products/TriangularMatrixMatrix.h"
#include "src/Core/products/TriangularSolverMatrix.h"
#include "src/Core/products/TriangularSolverVector.h"
#include "src/Core/BandMatrix.h"
#include "src/Core/BooleanRedux.h"
#include "src/Core/Select.h"
#include "src/Core/VectorwiseOp.h"
#include "src/Core/Random.h"
#include "src/Core/Replicate.h"
#include "src/Core/Reverse.h"
#include "src/Core/ArrayBase.h"
#include "src/Core/ArrayWrapper.h"
} // namespace Eigen
#include "src/Core/GlobalFunctions.h"
#include "src/Core/util/ReenableStupidWarnings.h"
#ifdef EIGEN2_SUPPORT
#include "Eigen2Support"
#endif
#endif // EIGEN_CORE_H

View File

@@ -1,7 +1,7 @@
#include "Core"
#include "LU"
#include "Cholesky"
#include "QR"
#include "SVD"
#include "Geometry"
#include "Eigenvalues"
#include "Core"
#include "LU"
#include "Cholesky"
#include "QR"
#include "SVD"
#include "Geometry"
#include "Eigenvalues"

View File

@@ -1,2 +1,2 @@
#include "Dense"
//#include "Sparse"
#include "Dense"
//#include "Sparse"

View File

@@ -1,82 +1,82 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// Eigen 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 3 of the License, or (at your option) any later version.
//
// Alternatively, 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 2 of
// the License, or (at your option) any later version.
//
// Eigen 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 or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN2SUPPORT_H
#define EIGEN2SUPPORT_H
#if (!defined(EIGEN2_SUPPORT)) || (!defined(EIGEN_CORE_H))
#error Eigen2 support must be enabled by defining EIGEN2_SUPPORT before including any Eigen header
#endif
#include "src/Core/util/DisableStupidWarnings.h"
namespace Eigen {
/** \defgroup Eigen2Support_Module Eigen2 support module
* This module provides a couple of deprecated functions improving the compatibility with Eigen2.
*
* To use it, define EIGEN2_SUPPORT before including any Eigen header
* \code
* #define EIGEN2_SUPPORT
* \endcode
*
*/
#include "src/Eigen2Support/Macros.h"
#include "src/Eigen2Support/Memory.h"
#include "src/Eigen2Support/Meta.h"
#include "src/Eigen2Support/Lazy.h"
#include "src/Eigen2Support/Cwise.h"
#include "src/Eigen2Support/CwiseOperators.h"
#include "src/Eigen2Support/TriangularSolver.h"
#include "src/Eigen2Support/Block.h"
#include "src/Eigen2Support/VectorBlock.h"
#include "src/Eigen2Support/Minor.h"
#include "src/Eigen2Support/MathFunctions.h"
} // namespace Eigen
#include "src/Core/util/ReenableStupidWarnings.h"
// Eigen2 used to include iostream
#include<iostream>
#define USING_PART_OF_NAMESPACE_EIGEN \
EIGEN_USING_MATRIX_TYPEDEFS \
using Eigen::Matrix; \
using Eigen::MatrixBase; \
using Eigen::ei_random; \
using Eigen::ei_real; \
using Eigen::ei_imag; \
using Eigen::ei_conj; \
using Eigen::ei_abs; \
using Eigen::ei_abs2; \
using Eigen::ei_sqrt; \
using Eigen::ei_exp; \
using Eigen::ei_log; \
using Eigen::ei_sin; \
using Eigen::ei_cos;
#endif // EIGEN2SUPPORT_H
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// Eigen 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 3 of the License, or (at your option) any later version.
//
// Alternatively, 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 2 of
// the License, or (at your option) any later version.
//
// Eigen 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 or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN2SUPPORT_H
#define EIGEN2SUPPORT_H
#if (!defined(EIGEN2_SUPPORT)) || (!defined(EIGEN_CORE_H))
#error Eigen2 support must be enabled by defining EIGEN2_SUPPORT before including any Eigen header
#endif
#include "src/Core/util/DisableStupidWarnings.h"
namespace Eigen {
/** \defgroup Eigen2Support_Module Eigen2 support module
* This module provides a couple of deprecated functions improving the compatibility with Eigen2.
*
* To use it, define EIGEN2_SUPPORT before including any Eigen header
* \code
* #define EIGEN2_SUPPORT
* \endcode
*
*/
#include "src/Eigen2Support/Macros.h"
#include "src/Eigen2Support/Memory.h"
#include "src/Eigen2Support/Meta.h"
#include "src/Eigen2Support/Lazy.h"
#include "src/Eigen2Support/Cwise.h"
#include "src/Eigen2Support/CwiseOperators.h"
#include "src/Eigen2Support/TriangularSolver.h"
#include "src/Eigen2Support/Block.h"
#include "src/Eigen2Support/VectorBlock.h"
#include "src/Eigen2Support/Minor.h"
#include "src/Eigen2Support/MathFunctions.h"
} // namespace Eigen
#include "src/Core/util/ReenableStupidWarnings.h"
// Eigen2 used to include iostream
#include<iostream>
#define USING_PART_OF_NAMESPACE_EIGEN \
EIGEN_USING_MATRIX_TYPEDEFS \
using Eigen::Matrix; \
using Eigen::MatrixBase; \
using Eigen::ei_random; \
using Eigen::ei_real; \
using Eigen::ei_imag; \
using Eigen::ei_conj; \
using Eigen::ei_abs; \
using Eigen::ei_abs2; \
using Eigen::ei_sqrt; \
using Eigen::ei_exp; \
using Eigen::ei_log; \
using Eigen::ei_sin; \
using Eigen::ei_cos;
#endif // EIGEN2SUPPORT_H

View File

@@ -1,44 +1,44 @@
#ifndef EIGEN_EIGENVALUES_MODULE_H
#define EIGEN_EIGENVALUES_MODULE_H
#include "Core"
#include "src/Core/util/DisableStupidWarnings.h"
#include "Cholesky"
#include "Jacobi"
#include "Householder"
#include "LU"
namespace Eigen {
/** \defgroup Eigenvalues_Module Eigenvalues module
*
*
*
* This module mainly provides various eigenvalue solvers.
* This module also provides some MatrixBase methods, including:
* - MatrixBase::eigenvalues(),
* - MatrixBase::operatorNorm()
*
* \code
* #include <Eigen/Eigenvalues>
* \endcode
*/
#include "src/Eigenvalues/Tridiagonalization.h"
#include "src/Eigenvalues/RealSchur.h"
#include "src/Eigenvalues/EigenSolver.h"
#include "src/Eigenvalues/SelfAdjointEigenSolver.h"
#include "src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h"
#include "src/Eigenvalues/HessenbergDecomposition.h"
#include "src/Eigenvalues/ComplexSchur.h"
#include "src/Eigenvalues/ComplexEigenSolver.h"
#include "src/Eigenvalues/MatrixBaseEigenvalues.h"
} // namespace Eigen
#include "src/Core/util/ReenableStupidWarnings.h"
#endif // EIGEN_EIGENVALUES_MODULE_H
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
#ifndef EIGEN_EIGENVALUES_MODULE_H
#define EIGEN_EIGENVALUES_MODULE_H
#include "Core"
#include "src/Core/util/DisableStupidWarnings.h"
#include "Cholesky"
#include "Jacobi"
#include "Householder"
#include "LU"
namespace Eigen {
/** \defgroup Eigenvalues_Module Eigenvalues module
*
*
*
* This module mainly provides various eigenvalue solvers.
* This module also provides some MatrixBase methods, including:
* - MatrixBase::eigenvalues(),
* - MatrixBase::operatorNorm()
*
* \code
* #include <Eigen/Eigenvalues>
* \endcode
*/
#include "src/Eigenvalues/Tridiagonalization.h"
#include "src/Eigenvalues/RealSchur.h"
#include "src/Eigenvalues/EigenSolver.h"
#include "src/Eigenvalues/SelfAdjointEigenSolver.h"
#include "src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h"
#include "src/Eigenvalues/HessenbergDecomposition.h"
#include "src/Eigenvalues/ComplexSchur.h"
#include "src/Eigenvalues/ComplexEigenSolver.h"
#include "src/Eigenvalues/MatrixBaseEigenvalues.h"
} // namespace Eigen
#include "src/Core/util/ReenableStupidWarnings.h"
#endif // EIGEN_EIGENVALUES_MODULE_H
/* vim: set filetype=cpp et sw=2 ts=2 ai: */

View File

@@ -1,67 +1,67 @@
#ifndef EIGEN_GEOMETRY_MODULE_H
#define EIGEN_GEOMETRY_MODULE_H
#include "Core"
#include "src/Core/util/DisableStupidWarnings.h"
#include "SVD"
#include "LU"
#include <limits>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
namespace Eigen {
/** \defgroup Geometry_Module Geometry module
*
*
*
* This module provides support for:
* - fixed-size homogeneous transformations
* - translation, scaling, 2D and 3D rotations
* - quaternions
* - \ref MatrixBase::cross() "cross product"
* - \ref MatrixBase::unitOrthogonal() "orthognal vector generation"
* - some linear components: parametrized-lines and hyperplanes
*
* \code
* #include <Eigen/Geometry>
* \endcode
*/
#include "src/Geometry/OrthoMethods.h"
#include "src/Geometry/EulerAngles.h"
#if EIGEN2_SUPPORT_STAGE > STAGE20_RESOLVE_API_CONFLICTS
#include "src/Geometry/Homogeneous.h"
#include "src/Geometry/RotationBase.h"
#include "src/Geometry/Rotation2D.h"
#include "src/Geometry/Quaternion.h"
#include "src/Geometry/AngleAxis.h"
#include "src/Geometry/Transform.h"
#include "src/Geometry/Translation.h"
#include "src/Geometry/Scaling.h"
#include "src/Geometry/Hyperplane.h"
#include "src/Geometry/ParametrizedLine.h"
#include "src/Geometry/AlignedBox.h"
#include "src/Geometry/Umeyama.h"
#if defined EIGEN_VECTORIZE_SSE
#include "src/Geometry/arch/Geometry_SSE.h"
#endif
#endif
#ifdef EIGEN2_SUPPORT
#include "src/Eigen2Support/Geometry/All.h"
#endif
} // namespace Eigen
#include "src/Core/util/ReenableStupidWarnings.h"
#endif // EIGEN_GEOMETRY_MODULE_H
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
#ifndef EIGEN_GEOMETRY_MODULE_H
#define EIGEN_GEOMETRY_MODULE_H
#include "Core"
#include "src/Core/util/DisableStupidWarnings.h"
#include "SVD"
#include "LU"
#include <limits>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
namespace Eigen {
/** \defgroup Geometry_Module Geometry module
*
*
*
* This module provides support for:
* - fixed-size homogeneous transformations
* - translation, scaling, 2D and 3D rotations
* - quaternions
* - \ref MatrixBase::cross() "cross product"
* - \ref MatrixBase::unitOrthogonal() "orthognal vector generation"
* - some linear components: parametrized-lines and hyperplanes
*
* \code
* #include <Eigen/Geometry>
* \endcode
*/
#include "src/Geometry/OrthoMethods.h"
#include "src/Geometry/EulerAngles.h"
#if EIGEN2_SUPPORT_STAGE > STAGE20_RESOLVE_API_CONFLICTS
#include "src/Geometry/Homogeneous.h"
#include "src/Geometry/RotationBase.h"
#include "src/Geometry/Rotation2D.h"
#include "src/Geometry/Quaternion.h"
#include "src/Geometry/AngleAxis.h"
#include "src/Geometry/Transform.h"
#include "src/Geometry/Translation.h"
#include "src/Geometry/Scaling.h"
#include "src/Geometry/Hyperplane.h"
#include "src/Geometry/ParametrizedLine.h"
#include "src/Geometry/AlignedBox.h"
#include "src/Geometry/Umeyama.h"
#if defined EIGEN_VECTORIZE_SSE
#include "src/Geometry/arch/Geometry_SSE.h"
#endif
#endif
#ifdef EIGEN2_SUPPORT
#include "src/Eigen2Support/Geometry/All.h"
#endif
} // namespace Eigen
#include "src/Core/util/ReenableStupidWarnings.h"
#endif // EIGEN_GEOMETRY_MODULE_H
/* vim: set filetype=cpp et sw=2 ts=2 ai: */

View File

@@ -1,27 +1,27 @@
#ifndef EIGEN_HOUSEHOLDER_MODULE_H
#define EIGEN_HOUSEHOLDER_MODULE_H
#include "Core"
#include "src/Core/util/DisableStupidWarnings.h"
namespace Eigen {
/** \defgroup Householder_Module Householder module
* This module provides Householder transformations.
*
* \code
* #include <Eigen/Householder>
* \endcode
*/
#include "src/Householder/Householder.h"
#include "src/Householder/HouseholderSequence.h"
#include "src/Householder/BlockHouseholder.h"
} // namespace Eigen
#include "src/Core/util/ReenableStupidWarnings.h"
#endif // EIGEN_HOUSEHOLDER_MODULE_H
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
#ifndef EIGEN_HOUSEHOLDER_MODULE_H
#define EIGEN_HOUSEHOLDER_MODULE_H
#include "Core"
#include "src/Core/util/DisableStupidWarnings.h"
namespace Eigen {
/** \defgroup Householder_Module Householder module
* This module provides Householder transformations.
*
* \code
* #include <Eigen/Householder>
* \endcode
*/
#include "src/Householder/Householder.h"
#include "src/Householder/HouseholderSequence.h"
#include "src/Householder/BlockHouseholder.h"
} // namespace Eigen
#include "src/Core/util/ReenableStupidWarnings.h"
#endif // EIGEN_HOUSEHOLDER_MODULE_H
/* vim: set filetype=cpp et sw=2 ts=2 ai: */

View File

@@ -1,30 +1,30 @@
#ifndef EIGEN_JACOBI_MODULE_H
#define EIGEN_JACOBI_MODULE_H
#include "Core"
#include "src/Core/util/DisableStupidWarnings.h"
namespace Eigen {
/** \defgroup Jacobi_Module Jacobi module
* This module provides Jacobi and Givens rotations.
*
* \code
* #include <Eigen/Jacobi>
* \endcode
*
* In addition to listed classes, it defines the two following MatrixBase methods to apply a Jacobi or Givens rotation:
* - MatrixBase::applyOnTheLeft()
* - MatrixBase::applyOnTheRight().
*/
#include "src/Jacobi/Jacobi.h"
} // namespace Eigen
#include "src/Core/util/ReenableStupidWarnings.h"
#endif // EIGEN_JACOBI_MODULE_H
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
#ifndef EIGEN_JACOBI_MODULE_H
#define EIGEN_JACOBI_MODULE_H
#include "Core"
#include "src/Core/util/DisableStupidWarnings.h"
namespace Eigen {
/** \defgroup Jacobi_Module Jacobi module
* This module provides Jacobi and Givens rotations.
*
* \code
* #include <Eigen/Jacobi>
* \endcode
*
* In addition to listed classes, it defines the two following MatrixBase methods to apply a Jacobi or Givens rotation:
* - MatrixBase::applyOnTheLeft()
* - MatrixBase::applyOnTheRight().
*/
#include "src/Jacobi/Jacobi.h"
} // namespace Eigen
#include "src/Core/util/ReenableStupidWarnings.h"
#endif // EIGEN_JACOBI_MODULE_H
/* vim: set filetype=cpp et sw=2 ts=2 ai: */

View File

@@ -1,42 +1,42 @@
#ifndef EIGEN_LU_MODULE_H
#define EIGEN_LU_MODULE_H
#include "Core"
#include "src/Core/util/DisableStupidWarnings.h"
namespace Eigen {
/** \defgroup LU_Module LU module
* This module includes %LU decomposition and related notions such as matrix inversion and determinant.
* This module defines the following MatrixBase methods:
* - MatrixBase::inverse()
* - MatrixBase::determinant()
*
* \code
* #include <Eigen/LU>
* \endcode
*/
#include "src/misc/Solve.h"
#include "src/misc/Kernel.h"
#include "src/misc/Image.h"
#include "src/LU/FullPivLU.h"
#include "src/LU/PartialPivLU.h"
#include "src/LU/Determinant.h"
#include "src/LU/Inverse.h"
#if defined EIGEN_VECTORIZE_SSE
#include "src/LU/arch/Inverse_SSE.h"
#endif
#ifdef EIGEN2_SUPPORT
#include "src/Eigen2Support/LU.h"
#endif
} // namespace Eigen
#include "src/Core/util/ReenableStupidWarnings.h"
#endif // EIGEN_LU_MODULE_H
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
#ifndef EIGEN_LU_MODULE_H
#define EIGEN_LU_MODULE_H
#include "Core"
#include "src/Core/util/DisableStupidWarnings.h"
namespace Eigen {
/** \defgroup LU_Module LU module
* This module includes %LU decomposition and related notions such as matrix inversion and determinant.
* This module defines the following MatrixBase methods:
* - MatrixBase::inverse()
* - MatrixBase::determinant()
*
* \code
* #include <Eigen/LU>
* \endcode
*/
#include "src/misc/Solve.h"
#include "src/misc/Kernel.h"
#include "src/misc/Image.h"
#include "src/LU/FullPivLU.h"
#include "src/LU/PartialPivLU.h"
#include "src/LU/Determinant.h"
#include "src/LU/Inverse.h"
#if defined EIGEN_VECTORIZE_SSE
#include "src/LU/arch/Inverse_SSE.h"
#endif
#ifdef EIGEN2_SUPPORT
#include "src/Eigen2Support/LU.h"
#endif
} // namespace Eigen
#include "src/Core/util/ReenableStupidWarnings.h"
#endif // EIGEN_LU_MODULE_H
/* vim: set filetype=cpp et sw=2 ts=2 ai: */

View File

@@ -1,36 +1,36 @@
#ifndef EIGEN_REGRESSION_MODULE_H
#define EIGEN_REGRESSION_MODULE_H
#ifndef EIGEN2_SUPPORT
#error LeastSquares is only available in Eigen2 support mode (define EIGEN2_SUPPORT)
#endif
// exclude from normal eigen3-only documentation
#ifdef EIGEN2_SUPPORT
#include "Core"
#include "src/Core/util/DisableStupidWarnings.h"
#include "Eigenvalues"
#include "Geometry"
namespace Eigen {
/** \defgroup LeastSquares_Module LeastSquares module
* This module provides linear regression and related features.
*
* \code
* #include <Eigen/LeastSquares>
* \endcode
*/
#include "src/Eigen2Support/LeastSquares.h"
} // namespace Eigen
#include "src/Core/util/ReenableStupidWarnings.h"
#endif // EIGEN2_SUPPORT
#endif // EIGEN_REGRESSION_MODULE_H
#ifndef EIGEN_REGRESSION_MODULE_H
#define EIGEN_REGRESSION_MODULE_H
#ifndef EIGEN2_SUPPORT
#error LeastSquares is only available in Eigen2 support mode (define EIGEN2_SUPPORT)
#endif
// exclude from normal eigen3-only documentation
#ifdef EIGEN2_SUPPORT
#include "Core"
#include "src/Core/util/DisableStupidWarnings.h"
#include "Eigenvalues"
#include "Geometry"
namespace Eigen {
/** \defgroup LeastSquares_Module LeastSquares module
* This module provides linear regression and related features.
*
* \code
* #include <Eigen/LeastSquares>
* \endcode
*/
#include "src/Eigen2Support/LeastSquares.h"
} // namespace Eigen
#include "src/Core/util/ReenableStupidWarnings.h"
#endif // EIGEN2_SUPPORT
#endif // EIGEN_REGRESSION_MODULE_H

View File

@@ -1,45 +1,45 @@
#ifndef EIGEN_QR_MODULE_H
#define EIGEN_QR_MODULE_H
#include "Core"
#include "src/Core/util/DisableStupidWarnings.h"
#include "Cholesky"
#include "Jacobi"
#include "Householder"
namespace Eigen {
/** \defgroup QR_Module QR module
*
*
*
* This module provides various QR decompositions
* This module also provides some MatrixBase methods, including:
* - MatrixBase::qr(),
*
* \code
* #include <Eigen/QR>
* \endcode
*/
#include "src/misc/Solve.h"
#include "src/QR/HouseholderQR.h"
#include "src/QR/FullPivHouseholderQR.h"
#include "src/QR/ColPivHouseholderQR.h"
#ifdef EIGEN2_SUPPORT
#include "src/Eigen2Support/QR.h"
#endif
} // namespace Eigen
#include "src/Core/util/ReenableStupidWarnings.h"
#ifdef EIGEN2_SUPPORT
#include "Eigenvalues"
#endif
#endif // EIGEN_QR_MODULE_H
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
#ifndef EIGEN_QR_MODULE_H
#define EIGEN_QR_MODULE_H
#include "Core"
#include "src/Core/util/DisableStupidWarnings.h"
#include "Cholesky"
#include "Jacobi"
#include "Householder"
namespace Eigen {
/** \defgroup QR_Module QR module
*
*
*
* This module provides various QR decompositions
* This module also provides some MatrixBase methods, including:
* - MatrixBase::qr(),
*
* \code
* #include <Eigen/QR>
* \endcode
*/
#include "src/misc/Solve.h"
#include "src/QR/HouseholderQR.h"
#include "src/QR/FullPivHouseholderQR.h"
#include "src/QR/ColPivHouseholderQR.h"
#ifdef EIGEN2_SUPPORT
#include "src/Eigen2Support/QR.h"
#endif
} // namespace Eigen
#include "src/Core/util/ReenableStupidWarnings.h"
#ifdef EIGEN2_SUPPORT
#include "Eigenvalues"
#endif
#endif // EIGEN_QR_MODULE_H
/* vim: set filetype=cpp et sw=2 ts=2 ai: */

View File

@@ -1,34 +1,34 @@
#ifndef EIGEN_QTMALLOC_MODULE_H
#define EIGEN_QTMALLOC_MODULE_H
#include "Core"
#if (!EIGEN_MALLOC_ALREADY_ALIGNED)
#include "src/Core/util/DisableStupidWarnings.h"
void *qMalloc(size_t size)
{
return Eigen::internal::aligned_malloc(size);
}
void qFree(void *ptr)
{
Eigen::internal::aligned_free(ptr);
}
void *qRealloc(void *ptr, size_t size)
{
void* newPtr = Eigen::internal::aligned_malloc(size);
memcpy(newPtr, ptr, size);
Eigen::internal::aligned_free(ptr);
return newPtr;
}
#include "src/Core/util/ReenableStupidWarnings.h"
#endif
#endif // EIGEN_QTMALLOC_MODULE_H
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
#ifndef EIGEN_QTMALLOC_MODULE_H
#define EIGEN_QTMALLOC_MODULE_H
#include "Core"
#if (!EIGEN_MALLOC_ALREADY_ALIGNED)
#include "src/Core/util/DisableStupidWarnings.h"
void *qMalloc(size_t size)
{
return Eigen::internal::aligned_malloc(size);
}
void qFree(void *ptr)
{
Eigen::internal::aligned_free(ptr);
}
void *qRealloc(void *ptr, size_t size)
{
void* newPtr = Eigen::internal::aligned_malloc(size);
memcpy(newPtr, ptr, size);
Eigen::internal::aligned_free(ptr);
return newPtr;
}
#include "src/Core/util/ReenableStupidWarnings.h"
#endif
#endif // EIGEN_QTMALLOC_MODULE_H
/* vim: set filetype=cpp et sw=2 ts=2 ai: */

View File

@@ -1,38 +1,38 @@
#ifndef EIGEN_SVD_MODULE_H
#define EIGEN_SVD_MODULE_H
#include "QR"
#include "Householder"
#include "Jacobi"
#include "src/Core/util/DisableStupidWarnings.h"
namespace Eigen {
/** \defgroup SVD_Module SVD module
*
*
*
* This module provides SVD decomposition for matrices (both real and complex).
* This decomposition is accessible via the following MatrixBase method:
* - MatrixBase::jacobiSvd()
*
* \code
* #include <Eigen/SVD>
* \endcode
*/
#include "src/misc/Solve.h"
#include "src/SVD/JacobiSVD.h"
#include "src/SVD/UpperBidiagonalization.h"
#ifdef EIGEN2_SUPPORT
#include "src/Eigen2Support/SVD.h"
#endif
} // namespace Eigen
#include "src/Core/util/ReenableStupidWarnings.h"
#endif // EIGEN_SVD_MODULE_H
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
#ifndef EIGEN_SVD_MODULE_H
#define EIGEN_SVD_MODULE_H
#include "QR"
#include "Householder"
#include "Jacobi"
#include "src/Core/util/DisableStupidWarnings.h"
namespace Eigen {
/** \defgroup SVD_Module SVD module
*
*
*
* This module provides SVD decomposition for matrices (both real and complex).
* This decomposition is accessible via the following MatrixBase method:
* - MatrixBase::jacobiSvd()
*
* \code
* #include <Eigen/SVD>
* \endcode
*/
#include "src/misc/Solve.h"
#include "src/SVD/JacobiSVD.h"
#include "src/SVD/UpperBidiagonalization.h"
#ifdef EIGEN2_SUPPORT
#include "src/Eigen2Support/SVD.h"
#endif
} // namespace Eigen
#include "src/Core/util/ReenableStupidWarnings.h"
#endif // EIGEN_SVD_MODULE_H
/* vim: set filetype=cpp et sw=2 ts=2 ai: */

View File

@@ -1,69 +1,69 @@
#ifndef EIGEN_SPARSE_MODULE_H
#define EIGEN_SPARSE_MODULE_H
#include "Core"
#include "src/Core/util/DisableStupidWarnings.h"
#include <vector>
#include <map>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#ifdef EIGEN2_SUPPORT
#define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
#endif
#ifndef EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
#error The sparse module API is not stable yet. To use it anyway, please define the EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET preprocessor token.
#endif
namespace Eigen {
/** \defgroup Sparse_Module Sparse module
*
*
*
* See the \ref TutorialSparse "Sparse tutorial"
*
* \code
* #include <Eigen/Sparse>
* \endcode
*/
/** The type used to identify a general sparse storage. */
struct Sparse {};
#include "src/Sparse/SparseUtil.h"
#include "src/Sparse/SparseMatrixBase.h"
#include "src/Sparse/CompressedStorage.h"
#include "src/Sparse/AmbiVector.h"
#include "src/Sparse/SparseMatrix.h"
#include "src/Sparse/DynamicSparseMatrix.h"
#include "src/Sparse/MappedSparseMatrix.h"
#include "src/Sparse/SparseVector.h"
#include "src/Sparse/CoreIterators.h"
#include "src/Sparse/SparseBlock.h"
#include "src/Sparse/SparseTranspose.h"
#include "src/Sparse/SparseCwiseUnaryOp.h"
#include "src/Sparse/SparseCwiseBinaryOp.h"
#include "src/Sparse/SparseDot.h"
#include "src/Sparse/SparseAssign.h"
#include "src/Sparse/SparseRedux.h"
#include "src/Sparse/SparseFuzzy.h"
#include "src/Sparse/SparseProduct.h"
#include "src/Sparse/SparseSparseProduct.h"
#include "src/Sparse/SparseDenseProduct.h"
#include "src/Sparse/SparseDiagonalProduct.h"
#include "src/Sparse/SparseTriangularView.h"
#include "src/Sparse/SparseSelfAdjointView.h"
#include "src/Sparse/TriangularSolver.h"
#include "src/Sparse/SparseView.h"
} // namespace Eigen
#include "src/Core/util/ReenableStupidWarnings.h"
#endif // EIGEN_SPARSE_MODULE_H
#ifndef EIGEN_SPARSE_MODULE_H
#define EIGEN_SPARSE_MODULE_H
#include "Core"
#include "src/Core/util/DisableStupidWarnings.h"
#include <vector>
#include <map>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#ifdef EIGEN2_SUPPORT
#define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
#endif
#ifndef EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
#error The sparse module API is not stable yet. To use it anyway, please define the EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET preprocessor token.
#endif
namespace Eigen {
/** \defgroup Sparse_Module Sparse module
*
*
*
* See the \ref TutorialSparse "Sparse tutorial"
*
* \code
* #include <Eigen/Sparse>
* \endcode
*/
/** The type used to identify a general sparse storage. */
struct Sparse {};
#include "src/Sparse/SparseUtil.h"
#include "src/Sparse/SparseMatrixBase.h"
#include "src/Sparse/CompressedStorage.h"
#include "src/Sparse/AmbiVector.h"
#include "src/Sparse/SparseMatrix.h"
#include "src/Sparse/DynamicSparseMatrix.h"
#include "src/Sparse/MappedSparseMatrix.h"
#include "src/Sparse/SparseVector.h"
#include "src/Sparse/CoreIterators.h"
#include "src/Sparse/SparseBlock.h"
#include "src/Sparse/SparseTranspose.h"
#include "src/Sparse/SparseCwiseUnaryOp.h"
#include "src/Sparse/SparseCwiseBinaryOp.h"
#include "src/Sparse/SparseDot.h"
#include "src/Sparse/SparseAssign.h"
#include "src/Sparse/SparseRedux.h"
#include "src/Sparse/SparseFuzzy.h"
#include "src/Sparse/SparseProduct.h"
#include "src/Sparse/SparseSparseProduct.h"
#include "src/Sparse/SparseDenseProduct.h"
#include "src/Sparse/SparseDiagonalProduct.h"
#include "src/Sparse/SparseTriangularView.h"
#include "src/Sparse/SparseSelfAdjointView.h"
#include "src/Sparse/TriangularSolver.h"
#include "src/Sparse/SparseView.h"
} // namespace Eigen
#include "src/Core/util/ReenableStupidWarnings.h"
#endif // EIGEN_SPARSE_MODULE_H

View File

@@ -1,42 +1,42 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
// Copyright (C) 2009 Hauke Heibel <hauke.heibel@googlemail.com>
//
// Eigen 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 3 of the License, or (at your option) any later version.
//
// Alternatively, 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 2 of
// the License, or (at your option) any later version.
//
// Eigen 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 or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_STDDEQUE_MODULE_H
#define EIGEN_STDDEQUE_MODULE_H
#include "Core"
#include <deque>
#if (defined(_MSC_VER) && defined(_WIN64)) /* MSVC auto aligns in 64 bit builds */
#define EIGEN_DEFINE_STL_DEQUE_SPECIALIZATION(...)
#else
#include "src/StlSupport/StdDeque.h"
#endif
#endif // EIGEN_STDDEQUE_MODULE_H
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
// Copyright (C) 2009 Hauke Heibel <hauke.heibel@googlemail.com>
//
// Eigen 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 3 of the License, or (at your option) any later version.
//
// Alternatively, 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 2 of
// the License, or (at your option) any later version.
//
// Eigen 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 or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_STDDEQUE_MODULE_H
#define EIGEN_STDDEQUE_MODULE_H
#include "Core"
#include <deque>
#if (defined(_MSC_VER) && defined(_WIN64)) /* MSVC auto aligns in 64 bit builds */
#define EIGEN_DEFINE_STL_DEQUE_SPECIALIZATION(...)
#else
#include "src/StlSupport/StdDeque.h"
#endif
#endif // EIGEN_STDDEQUE_MODULE_H

View File

@@ -1,41 +1,41 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Hauke Heibel <hauke.heibel@googlemail.com>
//
// Eigen 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 3 of the License, or (at your option) any later version.
//
// Alternatively, 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 2 of
// the License, or (at your option) any later version.
//
// Eigen 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 or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_STDLIST_MODULE_H
#define EIGEN_STDLIST_MODULE_H
#include "Core"
#include <list>
#if (defined(_MSC_VER) && defined(_WIN64)) /* MSVC auto aligns in 64 bit builds */
#define EIGEN_DEFINE_STL_LIST_SPECIALIZATION(...)
#else
#include "src/StlSupport/StdList.h"
#endif
#endif // EIGEN_STDLIST_MODULE_H
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Hauke Heibel <hauke.heibel@googlemail.com>
//
// Eigen 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 3 of the License, or (at your option) any later version.
//
// Alternatively, 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 2 of
// the License, or (at your option) any later version.
//
// Eigen 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 or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_STDLIST_MODULE_H
#define EIGEN_STDLIST_MODULE_H
#include "Core"
#include <list>
#if (defined(_MSC_VER) && defined(_WIN64)) /* MSVC auto aligns in 64 bit builds */
#define EIGEN_DEFINE_STL_LIST_SPECIALIZATION(...)
#else
#include "src/StlSupport/StdList.h"
#endif
#endif // EIGEN_STDLIST_MODULE_H

View File

@@ -1,42 +1,42 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
// Copyright (C) 2009 Hauke Heibel <hauke.heibel@googlemail.com>
//
// Eigen 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 3 of the License, or (at your option) any later version.
//
// Alternatively, 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 2 of
// the License, or (at your option) any later version.
//
// Eigen 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 or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_STDVECTOR_MODULE_H
#define EIGEN_STDVECTOR_MODULE_H
#include "Core"
#include <vector>
#if (defined(_MSC_VER) && defined(_WIN64)) /* MSVC auto aligns in 64 bit builds */
#define EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(...)
#else
#include "src/StlSupport/StdVector.h"
#endif
#endif // EIGEN_STDVECTOR_MODULE_H
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
// Copyright (C) 2009 Hauke Heibel <hauke.heibel@googlemail.com>
//
// Eigen 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 3 of the License, or (at your option) any later version.
//
// Alternatively, 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 2 of
// the License, or (at your option) any later version.
//
// Eigen 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 or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_STDVECTOR_MODULE_H
#define EIGEN_STDVECTOR_MODULE_H
#include "Core"
#include <vector>
#if (defined(_MSC_VER) && defined(_WIN64)) /* MSVC auto aligns in 64 bit builds */
#define EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(...)
#else
#include "src/StlSupport/StdVector.h"
#endif
#endif // EIGEN_STDVECTOR_MODULE_H

View File

@@ -23,6 +23,7 @@ set(SRC
blender_mesh.cpp
blender_object.cpp
blender_particles.cpp
blender_smoke.cpp
blender_python.cpp
blender_session.cpp
blender_shader.cpp

View File

@@ -280,6 +280,9 @@ void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::Object b_ob,
/* particle sync */
if (need_particle_update)
sync_particles(object, b_ob);
if(object_use_smoke(b_ob))
sync_smoke(object, b_ob);
object->tag_update(scene);
}

View File

@@ -0,0 +1,96 @@
/*
* Copyright 2011, Blender Foundation.
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* This program 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 for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "object.h"
#include "mesh.h"
#include "blender_sync.h"
#include "blender_util.h"
#include "util_foreach.h"
CCL_NAMESPACE_BEGIN
/* Utilities */
/* Smoke Sync */
/* Only looking for Smoke domains */
// TODO DG: disable rendering of smoke flow??
bool BlenderSync::object_use_smoke(BL::Object b_ob)
{
BL::Object::modifiers_iterator b_modifiers;
for(b_ob.modifiers.begin(b_modifiers); b_modifiers != b_ob.modifiers.end(); ++b_modifiers) {
BL::Modifier mod = (*b_modifiers);
if (mod.is_a(&RNA_SmokeModifier)) {
BL::SmokeModifier smd(mod);
if(smd.smoke_type() == BL::SmokeModifier::smoke_type_DOMAIN) {
BL::ID key = (BKE_object_is_modified(b_ob))? b_ob: b_ob.data();
Mesh *mesh = mesh_map.find(key);
if (mesh) {
return mesh->need_attribute(scene, ATTR_STD_SMOKE_DENSITY);
}
}
}
}
return false;
}
static BL::SmokeModifier *get_smoke(BL::Object b_ob)
{
BL::Object::modifiers_iterator b_modifiers;
for(b_ob.modifiers.begin(b_modifiers); b_modifiers != b_ob.modifiers.end(); ++b_modifiers) {
BL::Modifier mod = (*b_modifiers);
if (mod.is_a(&RNA_SmokeModifier)) {
BL::SmokeModifier *smd = (BL::SmokeModifier *)(&mod);
if(smd->smoke_type() == BL::SmokeModifier::smoke_type_DOMAIN) {
return smd;
}
}
}
return NULL;
}
void BlenderSync::sync_smoke(Object *ob, BL::Object b_ob)
{
BL::SmokeModifier *smd = get_smoke(b_ob);
BL::SmokeDomainSettings sds = smd->domain_settings();
ob->grid.clear();
ob->resolution = get_int3(sds.domain_resolution());
int length[3];
int numcells = rna_SmokeModifier_density_get_length(&sds.ptr, length);
if(numcells != 0)
{
vector<float> &grid = ob->grid;
grid.reserve(numcells);
grid.resize(numcells);
rna_SmokeModifier_density_get(&sds.ptr, &grid[0]);
}
}
CCL_NAMESPACE_END

View File

@@ -86,10 +86,12 @@ private:
void sync_mesh_motion(BL::Object b_ob, Mesh *mesh, int motion);
void sync_camera_motion(BL::Object b_ob, int motion);
void sync_particles(Object *ob, BL::Object b_ob);
void sync_smoke(Object *ob, BL::Object b_ob);
/* util */
void find_shader(BL::ID id, vector<uint>& used_shaders, int default_shader);
bool BKE_object_is_modified(BL::Object b_ob);
bool object_use_smoke(BL::Object b_ob);
bool object_is_mesh(BL::Object b_ob);
bool object_is_light(BL::Object b_ob);
bool object_need_particle_update(BL::Object b_ob);

View File

@@ -56,6 +56,9 @@ void rna_Scene_frame_set(void *scene, int frame, float subframe);
void BKE_image_user_frame_calc(void *iuser, int cfra, int fieldnr);
void BKE_image_user_file_path(void *iuser, void *ima, char *path);
int rna_SmokeModifier_density_get_length(PointerRNA *ptr, int length[3]);
void rna_SmokeModifier_density_get(PointerRNA *ptr, float *values);
}
CCL_NAMESPACE_BEGIN
@@ -155,6 +158,11 @@ static inline int4 get_int4(BL::Array<int, 4> array)
return make_int4(array[0], array[1], array[2], array[3]);
}
static inline int3 get_int3(BL::Array<int, 3> array)
{
return make_int3(array[0], array[1], array[2]);
}
static inline uint get_layer(BL::Array<int, 20> array)
{
uint layer = 0;

View File

@@ -55,6 +55,9 @@ KERNEL_TEX(float2, texture_float2, __light_background_conditional_cdf)
/* particles */
KERNEL_TEX(float4, texture_float4, __particles)
/* Smoke */
KERNEL_TEX(float, texture_float, __smoke_density)
/* shaders */
KERNEL_TEX(uint4, texture_uint4, __svm_nodes)
KERNEL_TEX(uint, texture_uint, __shader_flag)

View File

@@ -363,6 +363,7 @@ typedef enum AttributeStandard {
ATTR_STD_MOTION_PRE,
ATTR_STD_MOTION_POST,
ATTR_STD_PARTICLE,
ATTR_STD_SMOKE_DENSITY,
ATTR_STD_NUM,
ATTR_STD_NOT_FOUND = ~0

View File

@@ -272,6 +272,9 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT
case NODE_PARTICLE_INFO:
svm_node_particle_info(kg, sd, stack, node.y, node.z);
break;
case NODE_SMOKE_DENSITY:
svm_node_smoke_density(kg, sd, stack, node.y, node.z);
break;
#endif
case NODE_CONVERT:
svm_node_convert(sd, stack, node.y, node.z, node.w);

View File

@@ -122,5 +122,22 @@ __device void svm_node_particle_info(KernelGlobals *kg, ShaderData *sd, float *s
}
}
/* Smoke Density */
__device void svm_node_smoke_density(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset)
{
float data;
switch(type) {
case NODE_INFO_SMO_DEN: {
// DG TODO uint particle_id = object_particle_id(kg, sd->object);
// DG TODO data = smoke_density(kg, WHICH CELL IN GRID?);
// DG TODO stack_store_float(stack, out_offset, data);
break;
}
}
}
CCL_NAMESPACE_END

View File

@@ -89,7 +89,8 @@ typedef enum NodeType {
NODE_MIN_MAX,
NODE_LIGHT_FALLOFF,
NODE_OBJECT_INFO,
NODE_PARTICLE_INFO
NODE_PARTICLE_INFO,
NODE_SMOKE_DENSITY
} NodeType;
typedef enum NodeAttributeType {
@@ -119,6 +120,10 @@ typedef enum NodeParticleInfo {
NODE_INFO_PAR_LIFETIME
} NodeParticleInfo;
typedef enum NodeSmokeDensity {
NODE_INFO_SMO_DEN
} NodeSmokeDensity;
typedef enum NodeLightPath {
NODE_LP_camera = 0,
NODE_LP_shadow,

View File

@@ -1843,6 +1843,38 @@ void ParticleInfoNode::compile(OSLCompiler& compiler)
compiler.add(this, "node_particle_info");
}
/* Smoke Density */
SmokeDensityNode::SmokeDensityNode()
: ShaderNode("particle_info")
{
add_output("Density", SHADER_SOCKET_FLOAT);
}
void SmokeDensityNode::attributes(AttributeRequestSet *attributes)
{
if(!output("Density")->links.empty())
attributes->add(ATTR_STD_SMOKE_DENSITY);
ShaderNode::attributes(attributes);
}
void SmokeDensityNode::compile(SVMCompiler& compiler)
{
ShaderOutput *out;
out = output("Density");
if(!out->links.empty()) {
compiler.stack_assign(out);
compiler.add_node(NODE_SMOKE_DENSITY, NODE_INFO_SMO_DEN, out->stack_offset);
}
}
void SmokeDensityNode::compile(OSLCompiler& compiler)
{
compiler.add(this, "node_smoke_density");
}
/* Value */
ValueNode::ValueNode()

View File

@@ -296,6 +296,12 @@ public:
void attributes(AttributeRequestSet *attributes);
};
class SmokeDensityNode : public ShaderNode {
public:
SHADER_NODE_CLASS(SmokeDensityNode)
void attributes(AttributeRequestSet *attributes);
};
class ValueNode : public ShaderNode {
public:
SHADER_NODE_CLASS(ValueNode)

View File

@@ -167,7 +167,7 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
float uniform_scale;
float surface_area = 0.0f;
float pass_id = ob->pass_id;
float random_number = (float)ob->random_id * (1.0f/(float)0xFFFFFFFF);
float random_number = (float)ob->random_id * (1.0f/(float)0xFFFFFFFF)+0.5f;
if(transform_uniform_scale(tfm, uniform_scale)) {
map<Mesh*, float>::iterator it = surface_area_map.find(mesh);
@@ -281,6 +281,37 @@ void ObjectManager::device_update_particles(Device *device, DeviceScene *dscene,
device->tex_alloc("__particles", dscene->particles);
}
void ObjectManager::device_update_smoke(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
{
/* count smoke cells.
* adds one dummy particle at the beginning to avoid invalid lookups,
* in case a shader uses particle info without actual particle data.
*/
int num_cells = 1;
foreach(Object *ob, scene->objects)
num_cells += ob->grid.size();
float *density = dscene->smoke_density.resize(num_cells);
/* dummy particle */
// DG TODO density[0] = 0.0f;
int i = 0;
foreach(Object *ob, scene->objects) {
/* pack in texture */
for(i = 0; i < ob->grid.size(); i++) {
// DG TODO: use "*PARTICLE_SIZE"?
density[i] = ob->grid[i];
if(progress.get_cancel()) return;
}
}
device->tex_alloc("__smoke_density", dscene->smoke_density);
}
void ObjectManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
{
if(!need_update)
@@ -311,6 +342,11 @@ void ObjectManager::device_update(Device *device, DeviceScene *dscene, Scene *sc
if(progress.get_cancel()) return;
progress.set_status("Updating Objects", "Copying Smoke Density to device");
device_update_smoke(device, dscene, scene, progress);
if(progress.get_cancel()) return;
need_update = false;
}

View File

@@ -58,6 +58,10 @@ public:
int particle_id;
vector<Particle> particles;
/* Voxel / 3D volume data */
int3 resolution;
vector<float> grid;
Object();
~Object();
@@ -79,6 +83,7 @@ public:
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
void device_update_transforms(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
void device_update_particles(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
void device_update_smoke(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
void device_free(Device *device, DeviceScene *dscene);
void tag_update(Scene *scene);

View File

@@ -85,6 +85,9 @@ public:
/* particles */
device_vector<float4> particles;
/* smoke */
device_vector<float> smoke_density;
/* shaders */
device_vector<uint4> svm_nodes;
device_vector<uint> shader_flag;

View File

@@ -25,8 +25,7 @@
set(INC
intern
../memutil
../../extern/bullet2/src
../../extern/Eigen3
)
set(INC_SYS

View File

@@ -9,11 +9,10 @@ defs = ''
if env['WITH_BF_OPENMP']:
if env['OURPLATFORM'] == 'linuxcross':
incs += ' ' + env['BF_OPENMP_INC']
defs += ' PARALLEL=1'
defs += ' PARALLEL=1'
incs += ' ' + env['BF_PNG_INC'] + ' ' + env['BF_ZLIB_INC']
incs += ' intern ../../extern/bullet2/src ../memutil ../guardealloc '
incs += ' intern ../memutil ../guardealloc ../../extern/Eigen3 '
if env['WITH_BF_FFTW3']:
defs += ' WITH_FFTW3'

View File

@@ -53,6 +53,8 @@ float *smoke_get_velocity_x(struct FLUID_3D *fluid);
float *smoke_get_velocity_y(struct FLUID_3D *fluid);
float *smoke_get_velocity_z(struct FLUID_3D *fluid);
float *smoke_get_pressure(struct FLUID_3D *fluid);
/* Moving obstacle velocity provided by blender */
void smoke_get_ob_velocity(struct FLUID_3D *fluid, float **x, float **y, float **z);

View File

@@ -36,10 +36,16 @@
#include "float.h"
#include <iostream>
#include <Eigen/Dense>
#include <Eigen/Sparse>
#if PARALLEL==1
#include <omp.h>
#endif // PARALLEL
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
@@ -98,6 +104,9 @@ FLUID_3D::FLUID_3D(int *res, float *p0, float dtdef) :
_heatOld = new float[_totalCells];
_obstacles = new unsigned char[_totalCells]; // set 0 at end of step
// For debugging purposes
_pressure = new float[_totalCells];
// For threaded version:
_xVelocityTemp = new float[_totalCells];
_yVelocityTemp = new float[_totalCells];
@@ -126,13 +135,14 @@ FLUID_3D::FLUID_3D(int *res, float *p0, float dtdef) :
_yForce[x] = 0.0f;
_zForce[x] = 0.0f;
_obstacles[x] = false;
_pressure[x] = 0.0f;
}
// boundary conditions of the fluid domain
// set default values -> vertically non-colliding
_domainBcFront = true;
_domainBcFront = false;
_domainBcTop = false;
_domainBcLeft = true;
_domainBcLeft = false;
_domainBcBack = _domainBcFront;
_domainBcBottom = _domainBcTop;
_domainBcRight = _domainBcLeft;
@@ -206,6 +216,10 @@ FLUID_3D::~FLUID_3D()
if (_obstacles) delete[] _obstacles;
// if (_wTurbulence) delete _wTurbulence;
// for debugging purposes
if(_pressure)
delete[] _pressure;
if (_xVelocityTemp) delete[] _xVelocityTemp;
if (_yVelocityTemp) delete[] _yVelocityTemp;
if (_zVelocityTemp) delete[] _zVelocityTemp;
@@ -230,16 +244,6 @@ void FLUID_3D::initBlenderRNA(float *alpha, float *beta, float *dt_factor, float
//////////////////////////////////////////////////////////////////////
void FLUID_3D::step(float dt)
{
#if 0
// If border rules have been changed
if (_colloPrev != *_borderColli) {
printf("Border collisions changed\n");
// DG TODO: Need to check that no animated obstacle flags are overwritten
setBorderCollisions();
}
#endif
// DG: TODO for the moment redo border for every timestep since it's been deleted every time by moving obstacles
setBorderCollisions();
@@ -407,6 +411,17 @@ void FLUID_3D::step(float dt)
for (int i = 0; i < _totalCells; i++)
{
_xForce[i] = _yForce[i] = _zForce[i] = 0.0f;
/*
if(_density[i] < FLT_EPSILON)
{
// _density[i] = 0.0f;
_xVelocity[i] =
_yVelocity[i] =
_zVelocity[i] = 0.0f;
}
*/
}
}
@@ -739,6 +754,7 @@ void FLUID_3D::wipeBoundariesSL(int zBegin, int zEnd)
}
}
//////////////////////////////////////////////////////////////////////
// add forces to velocity field
//////////////////////////////////////////////////////////////////////
@@ -754,6 +770,7 @@ void FLUID_3D::addForce(int zBegin, int zEnd)
_zVelocityTemp[i] = _zVelocity[i] + _dt * _zForce[i];
}
}
//////////////////////////////////////////////////////////////////////
// project into divergence free field
//////////////////////////////////////////////////////////////////////
@@ -761,14 +778,46 @@ void FLUID_3D::project()
{
int x, y, z;
size_t index;
#if USE_NEW_CG == 1
VectorXf p(_totalCells);
float *_pressure = new float[_totalCells];
ArrayXd A0(_totalCells);
ArrayXd Ai(_totalCells);
ArrayXd Aj(_totalCells);
ArrayXd Ak(_totalCells);
A0.setZero(_totalCells);
Ai.setZero(_totalCells);
Aj.setZero(_totalCells);
Ak.setZero(_totalCells);
p.setZero(_totalCells);
ArrayXd gti(_totalCells); // gridToIndex
unsigned int linearIndex = 0;
for (z = 0; z < _zRes; z++)
for (y = 0; y < _yRes; y++)
for (x = 0; x < _xRes; x++)
if(!_obstacles[FINDEX(x, y, z)])
{
gti[FINDEX(x, y, z)] = linearIndex;
linearIndex++;
}
VectorXf b(linearIndex);
b.setZero(linearIndex);
SparseMatrix<float,RowMajor> A(linearIndex, linearIndex);
A.reserve(VectorXi::Constant(linearIndex, 7));
#endif
// float *_pressure = new float[_totalCells];
float *_divergence = new float[_totalCells];
memset(_pressure, 0, sizeof(float)*_totalCells);
memset(_divergence, 0, sizeof(float)*_totalCells);
// set velocity and pressure inside of obstacles to zero
// set VELOCITY and PRESSURE inside of obstacles cells to zero
setObstacleBoundaries(_pressure, 0, _zRes);
// copy out the boundaries
@@ -781,35 +830,6 @@ void FLUID_3D::project()
if(!_domainBcTop) setNeumannZ(_zVelocity, _res, 0, _zRes);
else setZeroZ(_zVelocity, _res, 0, _zRes);
/*
{
float maxx = 0, maxy = 0, maxz = 0;
for(unsigned int i = 0; i < _xRes * _yRes * _zRes; i++)
{
if(_xVelocity[i] > maxx)
maxx = _xVelocity[i];
if(_yVelocity[i] > maxy)
maxy = _yVelocity[i];
if(_zVelocity[i] > maxz)
maxz = _zVelocity[i];
}
printf("Max velx: %f, vely: %f, velz: %f\n", maxx, maxy, maxz);
}
*/
/*
{
float maxvalue = 0;
for(unsigned int i = 0; i < _xRes * _yRes * _zRes; i++)
{
if(_heat[i] > maxvalue)
maxvalue = _heat[i];
}
printf("Max heat: %f\n", maxvalue);
}
*/
// calculate divergence
index = _slabSize + _xRes + 1;
for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
@@ -823,7 +843,6 @@ void FLUID_3D::project()
continue;
}
float xright = _xVelocity[index + 1];
float xleft = _xVelocity[index - 1];
float yup = _yVelocity[index + _xRes];
@@ -838,12 +857,12 @@ void FLUID_3D::project()
if(_obstacles[index+_slabSize]) ztop = - _zVelocity[index];
if(_obstacles[index-_slabSize]) zbottom = - _zVelocity[index];
if(_obstacles[index+1] & 8) xright += _xVelocityOb[index + 1];
if(_obstacles[index-1] & 8) xleft += _xVelocityOb[index - 1];
if(_obstacles[index+_xRes] & 8) yup += _yVelocityOb[index + _xRes];
if(_obstacles[index-_xRes] & 8) ydown += _yVelocityOb[index - _xRes];
if(_obstacles[index+_slabSize] & 8) ztop += _zVelocityOb[index + _slabSize];
if(_obstacles[index-_slabSize] & 8) zbottom += _zVelocityOb[index - _slabSize];
if(_obstacles[index+1]) xright += _xVelocityOb[index + 1];
if(_obstacles[index-1]) xleft += _xVelocityOb[index - 1];
if(_obstacles[index+_xRes]) yup += _yVelocityOb[index + _xRes];
if(_obstacles[index-_xRes]) ydown += _yVelocityOb[index - _xRes];
if(_obstacles[index+_slabSize]) ztop += _zVelocityOb[index + _slabSize];
if(_obstacles[index-_slabSize]) zbottom += _zVelocityOb[index - _slabSize];
_divergence[index] = -_dx * 0.5f * (
xright - xleft +
@@ -854,37 +873,162 @@ void FLUID_3D::project()
_pressure[index] = 0.0f;
}
/*
float scale = 1.0; // DG TODO: make this global and incooperate this into other functions
#if USE_NEW_CG == 1
for (z = 0; z < _zRes; z++)
for (y = 0; y < _yRes; y++)
for (x = 0; x < _xRes; x++)
{
float maxvalue = 0;
for(unsigned int i = 0; i < _xRes * _yRes * _zRes; i++)
{
if(_divergence[i] > maxvalue)
maxvalue = _divergence[i];
if(!_obstacles[FINDEX(x, y, z)])
{
// +x
if(x < _xRes -1)
{ if(!_obstacles[FINDEX(x + 1, y, z)]) A0[FINDEX(x, y, z)] += scale; }
else
A0[FINDEX(x, y, z)] += scale;
// -x
if(x > 0)
{ if(!_obstacles[FINDEX(x - 1, y, z)]) A0[FINDEX(x, y, z)] += scale; }
else
A0[FINDEX(x, y, z)] += scale;
// +y
if(y < _yRes - 1)
{ if(!_obstacles[FINDEX(x, y + 1, z)]) A0[FINDEX(x, y, z)] += scale; }
else
A0[FINDEX(x, y, z)] += scale;
// -y
if(y > 0)
{ if(!_obstacles[FINDEX(x, y - 1, z)]) A0[FINDEX(x, y, z)] += scale; }
else
A0[FINDEX(x, y, z)] += scale;
// +z
if(z < _zRes - 1)
{ if(!_obstacles[FINDEX(x, y, z + 1)]) A0[FINDEX(x, y, z)] += scale; }
else
A0[FINDEX(x, y, z)] += scale;
// -z
if(z > 0)
{ if(!_obstacles[FINDEX(x, y, z - 1)]) A0[FINDEX(x, y, z)] += scale; }
else
A0[FINDEX(x, y, z)] += scale;
}
}
printf("Max divergence: %f\n", maxvalue);
}
*/
copyBorderAll(_pressure, 0, _zRes);
/*
for (z = 0; z < _zRes; z++)
for (y = 0; y < _yRes; y++)
for (x = 0; x < _xRes; x++)
{
float maxvalue = 0;
for(unsigned int i = 0; i < _xRes * _yRes * _zRes; i++)
{
if(_pressure[i] > maxvalue)
maxvalue = _pressure[i];
}
printf("Max pressure BEFORE: %f\n", maxvalue);
if(!_obstacles[FINDEX(x, y, z)])
{
// x
if(x < _xRes - 1)
{ if(!_obstacles[FINDEX(x + 1, y, z)]) Ai[FINDEX(x, y, z)] = -scale; }
else
Ai[FINDEX(x, y, z)] = -scale;
// y
if(y < _yRes - 1)
{ if(!_obstacles[FINDEX(x, y + 1, z)]) Aj[FINDEX(x, y, z)] = -scale; }
else
Aj[FINDEX(x, y, z)] = -scale;
// z
if(z < _zRes - 1)
{ if(!_obstacles[FINDEX(x, y, z + 1)]) Ak[FINDEX(x, y, z)] = -scale; }
else
Ak[FINDEX(x, y, z)] = -scale;
}
}
*/
unsigned int rowCount = 0;
for (z = 0; z < _zRes; z++)
for (y = 0; y < _yRes; y++)
for (x = 0; x < _xRes; x++)
if (!_obstacles[FINDEX(x,y,z)])
{
rowCount = gti(FINDEX(x, y, z));
/*
if((x > 0) && (Ai[FINDEX(x - 1, y, z)] < 0))
A.insert(rowCount, gti(FINDEX(x - 1, y, z))) = Ai[FINDEX(x - 1, y, z)];
if((y > 0) && (Aj[FINDEX(x, y - 1, z)] < 0))
A.insert(rowCount, gti(FINDEX(x, y - 1, z))) = Aj[FINDEX(x, y - 1, z)];
if((z > 0) && (Ak[FINDEX(x, y, z - 1)] < 0))
A.insert(rowCount, gti(FINDEX(x, y, z - 1))) = Ak[FINDEX(x, y, z - 1)];
*/
if(A0[FINDEX(x, y, z)] > 0)
A.insert(rowCount, gti(FINDEX(x, y, z))) = A0[FINDEX(x, y, z)];
if((x + 1 < _xRes) && (Ai[FINDEX(x, y, z)] < 0))
A.insert(rowCount, gti(FINDEX(x + 1, y, z))) = Ai[FINDEX(x, y, z)];
if((y + 1 < _yRes) && (Aj[FINDEX(x, y, z)] < 0))
A.insert(rowCount, gti(FINDEX(x, y + 1, z))) = Aj[FINDEX(x, y, z)];
if((z + 1 < _zRes) && (Ak[FINDEX(x, y, z)] < 0))
A.insert(rowCount, gti(FINDEX(x, y, z + 1))) = Ak[FINDEX(x, y, z)];
// rowCount++;
}
for (z = 0; z < _zRes; z++)
for (y = 0; y < _yRes; y++)
for (x = 0; x < _xRes; x++)
if (!_obstacles[FINDEX(x,y,z)])
b[gti(FINDEX(x, y, z))] = _divergence[FINDEX(x,y,z)];
#endif
// copyBorderAll(_pressure, 0, _zRes);
// solve Poisson equation
solvePressurePre(_pressure, _divergence, _obstacles);
#if USE_NEW_CG == 1
A.makeCompressed();
VectorXf result(linearIndex);
result.setZero(linearIndex);
ConjugateGradient< SparseMatrix<float, RowMajor>, Upper > solver;
solver.setMaxIterations(300);
solver.setTolerance(1e-06);
solver.compute(A);
if(solver.info() != Success)
{
// decomposition failed
printf("Solver error: Cannot create decomposition: %d\n", solver.info());
}
else
{
result = solver.solve(b);
if(solver.info() != Success)
{
// solving failed
printf("Solver error: Cannot solve equation: %d\n", solver.info());
}
else
printf("Solver finished.\n");
std::cout << "#iterations: " << solver.iterations() << std::endl;
std::cout << "estimated error: " << solver.error() << std::endl;
}
#else
solvePressurePre(_pressure, _divergence, _obstacles);
#endif
#if 0
for(unsigned int i = 0; i < _xRes * _yRes * _zRes; i++)
{
float value = (_pressure[i] - result[i]);
if(value > 0.01)
printf("error: p: %f, b: %f\n", _pressure[i], result[i]);
}
#endif
#if 1
{
float maxvalue = 0;
for(unsigned int i = 0; i < _xRes * _yRes * _zRes; i++)
@@ -906,8 +1050,9 @@ void FLUID_3D::project()
}
// printf("Max pressure: %f, dx: %f\n", maxvalue, _dx);
}
setObstaclePressure(_pressure, 0, _zRes);
#endif
// DG TODO: check this function, for now this is done in the next function
// setObstaclePressure(_pressure, 0, _zRes);
// project out solution
float invDx = 1.0f / _dx;
@@ -916,17 +1061,55 @@ void FLUID_3D::project()
for (y = 1; y < _yRes - 1; y++, index += 2)
for (x = 1; x < _xRes - 1; x++, index++)
{
float vMask[3] = {1.0f, 1.0f, 1.0f}, vObst[3] = {0, 0, 0};
float vR = 0.0f, vL = 0.0f, vT = 0.0f, vB = 0.0f, vD = 0.0f, vU = 0.0f;
#if USE_NEW_CG == 1
float pC = result[gti(FINDEX(x, y, z))]; // center
float pR = result[gti(FINDEX(x + 1, y, z))]; // right
float pL = result[gti(FINDEX(x - 1, y, z))]; // left
float pU = result[gti(FINDEX(x, y + 1, z))]; // top
float pD = result[gti(FINDEX(x, y - 1, z))]; // bottom
float pT = result[gti(FINDEX(x, y, z + 1))]; // Up
float pB = result[gti(FINDEX(x, y, z - 1))]; // Down
#else
float pC = _pressure[index]; // center
float pR = _pressure[index + 1]; // right
float pL = _pressure[index - 1]; // left
float pU = _pressure[index + _xRes]; // Up
float pD = _pressure[index - _xRes]; // Down
float pT = _pressure[index + _slabSize]; // top
float pB = _pressure[index - _slabSize]; // bottom
#endif
if(!_obstacles[index])
{
_xVelocity[index] -= 0.5f * (_pressure[index + 1] - _pressure[index - 1]) * invDx;
_yVelocity[index] -= 0.5f * (_pressure[index + _xRes] - _pressure[index - _xRes]) * invDx;
_zVelocity[index] -= 0.5f * (_pressure[index + _slabSize] - _pressure[index - _slabSize]) * invDx;
// DG TODO: What if obstacle is left + right and one is moving?
if(_obstacles[index+1]) { pR = pC; vObst[0] = _xVelocityOb[index + 1]; vMask[0] = 0; }
if(_obstacles[index-1]) { pL = pC; vObst[0] = _xVelocityOb[index - 1]; vMask[0] = 0; }
if(_obstacles[index+_xRes]) { pU = pC; vObst[1] = _yVelocityOb[index + _xRes]; vMask[1] = 0; }
if(_obstacles[index-_xRes]) { pD = pC; vObst[1] = _yVelocityOb[index - _xRes]; vMask[1] = 0; }
if(_obstacles[index+_slabSize]) { pT = pC; vObst[2] = _zVelocityOb[index + _slabSize]; vMask[2] = 0; }
if(_obstacles[index-_slabSize]) { pB = pC; vObst[2] = _zVelocityOb[index - _slabSize]; vMask[2] = 0; }
_xVelocity[index] -= 0.5f * (pR - pL) * invDx;
_yVelocity[index] -= 0.5f * (pU - pD) * invDx;
_zVelocity[index] -= 0.5f * (pT - pB) * invDx;
_xVelocity[index] = (vMask[0] * _xVelocity[index]) + vObst[0];
_yVelocity[index] = (vMask[1] * _yVelocity[index]) + vObst[1];
_zVelocity[index] = (vMask[2] * _zVelocity[index]) + vObst[2];
}
else
{
_xVelocity[index] = _xVelocityOb[index];
_yVelocity[index] = _yVelocityOb[index];
_zVelocity[index] = _zVelocityOb[index];
}
}
setObstacleVelocity(0, _zRes);
// setObstacleVelocity(0, _zRes);
if (_pressure) delete[] _pressure;
// if (_pressure) delete[] _pressure;
if (_divergence) delete[] _divergence;
}
@@ -1154,8 +1337,9 @@ void FLUID_3D::setObstacleBoundaries(float *_pressure, int zBegin, int zEnd)
if (top) counter++;
if (bottom) counter++;
if (counter < 3)
_obstacles[index] = EMPTY;
// DG TODO: Do not shrink obstacles for now
// if (counter < 3)
// _obstacles[index] = EMPTY;
}
if (_obstacles[index])
{
@@ -1190,6 +1374,9 @@ void FLUID_3D::addBuoyancy(float *heat, float *density, int zBegin, int zEnd)
//////////////////////////////////////////////////////////////////////
// add vorticity to the force field
//////////////////////////////////////////////////////////////////////
#define VORT_VEL(i, j) \
((_obstacles[obpos[(i)]] & 8) ? ((abs(objvelocity[(j)][obpos[(i)]]) > FLT_EPSILON) ? objvelocity[(j)][obpos[(i)]] : velocity[(j)][index]) : velocity[(j)][obpos[(i)]])
void FLUID_3D::addVorticity(int zBegin, int zEnd)
{
//int x,y,z,index;
@@ -1225,9 +1412,18 @@ void FLUID_3D::addVorticity(int zBegin, int zEnd)
float gridSize = 0.5f / _dx;
//index = _slabSize + _xRes + 1;
float *velocity[3];
float *objvelocity[3];
velocity[0] = _xVelocity;
velocity[1] = _yVelocity;
velocity[2] = _zVelocity;
objvelocity[0] = _xVelocityOb;
objvelocity[1] = _yVelocityOb;
objvelocity[2] = _zVelocityOb;
size_t vIndex=_xRes + 1;
for (int z = zBegin + bb1; z < (zEnd - bt1); z++)
{
size_t index = index_ +(z-1)*_slabSize;
@@ -1237,25 +1433,47 @@ void FLUID_3D::addVorticity(int zBegin, int zEnd)
{
for (int x = 1; x < _xRes - 1; x++, index++)
{
if (!_obstacles[index])
{
int obpos[6];
int up = _obstacles[index + _xRes] ? index : index + _xRes;
int down = _obstacles[index - _xRes] ? index : index - _xRes;
float dy = (up == index || down == index) ? 1.0f / _dx : gridSize;
int out = _obstacles[index + _slabSize] ? index : index + _slabSize;
int in = _obstacles[index - _slabSize] ? index : index - _slabSize;
float dz = (out == index || in == index) ? 1.0f / _dx : gridSize;
int right = _obstacles[index + 1] ? index : index + 1;
int left = _obstacles[index - 1] ? index : index - 1;
float dx = (right == index || left == index) ? 1.0f / _dx : gridSize;
obpos[0] = (_obstacles[index + _xRes] == 1) ? index : index + _xRes; // up
obpos[1] = (_obstacles[index - _xRes] == 1) ? index : index - _xRes; // down
float dy = (obpos[0] == index || obpos[1] == index) ? 1.0f / _dx : gridSize;
_xVorticity[vIndex] = (_zVelocity[up] - _zVelocity[down]) * dy + (-_yVelocity[out] + _yVelocity[in]) * dz;
_yVorticity[vIndex] = (_xVelocity[out] - _xVelocity[in]) * dz + (-_zVelocity[right] + _zVelocity[left]) * dx;
_zVorticity[vIndex] = (_yVelocity[right] - _yVelocity[left]) * dx + (-_xVelocity[up] + _xVelocity[down])* dy;
obpos[2] = (_obstacles[index + _slabSize] == 1) ? index : index + _slabSize; // out
obpos[3] = (_obstacles[index - _slabSize] == 1) ? index : index - _slabSize; // in
float dz = (obpos[2] == index || obpos[3] == index) ? 1.0f / _dx : gridSize;
_vorticity[vIndex] = sqrtf(_xVorticity[vIndex] * _xVorticity[vIndex] +
obpos[4] = (_obstacles[index + 1] == 1) ? index : index + 1; // right
obpos[5] = (_obstacles[index - 1] == 1) ? index : index - 1; // left
float dx = (obpos[4] == index || obpos[5] == index) ? 1.0f / _dx : gridSize;
float xV[2], yV[2], zV[2];
zV[1] = VORT_VEL(0, 2);
zV[0] = VORT_VEL(1, 2);
yV[1] = VORT_VEL(2, 1);
yV[0] = VORT_VEL(3, 1);
_xVorticity[vIndex] = (zV[1] - zV[0]) * dy + (-yV[1] + yV[0]) * dz;
xV[1] = VORT_VEL(2, 0);
xV[0] = VORT_VEL(3, 0);
zV[1] = VORT_VEL(4, 2);
zV[0] = VORT_VEL(5, 2);
_yVorticity[vIndex] = (xV[1] - xV[0]) * dz + (-zV[1] + zV[0]) * dx;
yV[1] = VORT_VEL(4, 1);
yV[0] = VORT_VEL(5, 1);
xV[1] = VORT_VEL(0, 0);
xV[0] = VORT_VEL(1, 0);
_zVorticity[vIndex] = (yV[1] - yV[0]) * dx + (-xV[1] + xV[0])* dy;
_vorticity[vIndex] = sqrtf(_xVorticity[vIndex] * _xVorticity[vIndex] +
_yVorticity[vIndex] * _yVorticity[vIndex] +
_zVorticity[vIndex] * _zVorticity[vIndex]);
}
vIndex++;
}
vIndex+=2;
@@ -1265,7 +1483,7 @@ void FLUID_3D::addVorticity(int zBegin, int zEnd)
// calculate normalized vorticity vectors
float eps = _vorticityEps;
//index = _slabSize + _xRes + 1;
vIndex=_slabSize + _xRes + 1;
@@ -1284,15 +1502,18 @@ void FLUID_3D::addVorticity(int zBegin, int zEnd)
{
float N[3];
int up = _obstacles[index + _xRes] ? vIndex : vIndex + _xRes;
int down = _obstacles[index - _xRes] ? vIndex : vIndex - _xRes;
int up = (_obstacles[index + _xRes] == 1) ? vIndex : vIndex + _xRes;
int down = (_obstacles[index - _xRes] == 1) ? vIndex : vIndex - _xRes;
float dy = (up == vIndex || down == vIndex) ? 1.0f / _dx : gridSize;
int out = _obstacles[index + _slabSize] ? vIndex : vIndex + _slabSize;
int in = _obstacles[index - _slabSize] ? vIndex : vIndex - _slabSize;
int out = (_obstacles[index + _slabSize] == 1) ? vIndex : vIndex + _slabSize;
int in = (_obstacles[index - _slabSize] == 1) ? vIndex : vIndex - _slabSize;
float dz = (out == vIndex || in == vIndex) ? 1.0f / _dx : gridSize;
int right = _obstacles[index + 1] ? vIndex : vIndex + 1;
int left = _obstacles[index - 1] ? vIndex : vIndex - 1;
int right = (_obstacles[index + 1] == 1) ? vIndex : vIndex + 1;
int left = (_obstacles[index - 1] == 1) ? vIndex : vIndex - 1;
float dx = (right == vIndex || left == vIndex) ? 1.0f / _dx : gridSize;
N[0] = (_vorticity[right] - _vorticity[left]) * dx;
N[1] = (_vorticity[up] - _vorticity[down]) * dy;
N[2] = (_vorticity[out] - _vorticity[in]) * dz;
@@ -1309,20 +1530,20 @@ void FLUID_3D::addVorticity(int zBegin, int zEnd)
_yForce[index] += (N[2] * _xVorticity[vIndex] - N[0] * _zVorticity[vIndex]) * _dx * eps;
_zForce[index] += (N[0] * _yVorticity[vIndex] - N[1] * _xVorticity[vIndex]) * _dx * eps;
}
} // if
vIndex++;
} // x loop
vIndex+=2;
} // y loop
//vIndex+=2*_xRes;
} // z loop
} // if
vIndex++;
} // x loop
vIndex+=2;
} // y loop
//vIndex+=2*_xRes;
} // z loop
if (_xVorticity) delete[] _xVorticity;
if (_yVorticity) delete[] _yVorticity;
if (_zVorticity) delete[] _zVorticity;
if (_vorticity) delete[] _vorticity;
}
#undef CURL_VEL
void FLUID_3D::advectMacCormackBegin(int zBegin, int zEnd)
{
@@ -1393,38 +1614,10 @@ void FLUID_3D::advectMacCormackEnd2(int zBegin, int zEnd)
setZeroBorder(_density, res, zBegin, zEnd);
setZeroBorder(_heat, res, zBegin, zEnd);
#if 0
{
const size_t index_ = _slabSize + _xRes + 1;
int bb=0;
int bt=0;
if (zBegin == 0) {bb = 1;}
if (zEnd == _zRes) {bt = 1;}
for (int z = zBegin + bb; z < zEnd - bt; z++)
{
size_t index = index_ +(z-1)*_slabSize;
for (int y = 1; y < _yRes - 1; y++, index += 2)
{
for (int x = 1; x < _xRes - 1; x++, index++)
{
// clean custom velocities from moving obstacles again
if (_obstacles[index])
{
_xVelocity[index] =
_yVelocity[index] =
_zVelocity[index] = 0.0f;
}
}
}
}
}
#endif
/*int begin=zBegin * _slabSize;
int end=begin + (zEnd - zBegin) * _slabSize;
for (int x = begin; x < end; x++)
_xForce[x] = _yForce[x] = 0.0f;*/
}

View File

@@ -43,6 +43,16 @@ using namespace std;
using namespace BasicVector;
class WTURBULENCE;
#define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
#include <Eigen/Dense>
#include <Eigen/Sparse>
using namespace Eigen;
#define USE_NEW_CG 0
// Fluid index
#define FINDEX(indexX, indexY, indexZ) ((indexZ) * _xRes * _yRes + (indexY) * _xRes + (indexX))
class FLUID_3D
{
public:
@@ -105,9 +115,12 @@ class FLUID_3D
float* _xForce;
float* _yForce;
float* _zForce;
unsigned char* _obstacles; /* only used (useful) for static obstacles like domain boundaries */
unsigned char* _obstacles; /* only used (usefull) for static obstacles like domain boundaries */
unsigned char* _obstaclesAnim;
// for debug purposes
float *_pressure;
// Required for proper threading:
float* _xVelocityTemp;
float* _yVelocityTemp;
@@ -159,7 +172,23 @@ class FLUID_3D
void project();
void diffuseHeat();
void solvePressure(float* field, float* b, unsigned char* skip);
#if USE_NEW_CG == 1
void solvePressurePre(VectorXf &b, SparseMatrix<float,RowMajor> &A, ArrayXd &gti, VectorXf &result);
#else
void solvePressurePre(float* field, float* b, unsigned char* skip);
// diagonal preconditioner
void precond_init_diag(float *precond, float* field, unsigned char* skip, size_t index);
void precond_apply_diag(float *dest, float* source, float *precond, unsigned char* skip, size_t index);
// modified incomplete cholesky preconditioner
void precond_init_mic(float *precond, float* field, unsigned char* skip, size_t index);
void precond_apply_mic(float *dest, float* source, float *precond, unsigned char* skip, size_t index);
#endif
void solvePressureJacobian(float* p, float* d, unsigned char* ob);
void solveHeat(float* field, float* b, unsigned char* skip);

View File

@@ -1,6 +1,6 @@
/** \file smoke/intern/FLUID_3D_SOLVERS.cpp
* \ingroup smoke
*/
* \ingroup smoke
*/
//////////////////////////////////////////////////////////////////////
// This file is part of Wavelet Turbulence.
//
@@ -50,121 +50,167 @@ void FLUID_3D::solveHeat(float* field, float* b, unsigned char* skip)
_q = new float[_totalCells]; // set 0
_Acenter = new float[_totalCells]; // set 0
memset(_residual, 0, sizeof(float)*_totalCells);
memset(_residual, 0, sizeof(float)*_totalCells);
memset(_q, 0, sizeof(float)*_totalCells);
memset(_direction, 0, sizeof(float)*_totalCells);
memset(_Acenter, 0, sizeof(float)*_totalCells);
float deltaNew = 0.0f;
// r = b - Ax
index = _slabSize + _xRes + 1;
for (z = 1; z < _zRes - 1; z++, index += twoxr)
for (y = 1; y < _yRes - 1; y++, index += 2)
for (x = 1; x < _xRes - 1; x++, index++)
{
// if the cell is a variable
_Acenter[index] = 1.0f;
if (!skip[index])
{
// set the matrix to the Poisson stencil in order
if (!skip[index + 1]) _Acenter[index] += heatConst;
if (!skip[index - 1]) _Acenter[index] += heatConst;
if (!skip[index + _xRes]) _Acenter[index] += heatConst;
if (!skip[index - _xRes]) _Acenter[index] += heatConst;
if (!skip[index + _slabSize]) _Acenter[index] += heatConst;
if (!skip[index - _slabSize]) _Acenter[index] += heatConst;
// r = b - Ax
index = _slabSize + _xRes + 1;
for (z = 1; z < _zRes - 1; z++, index += twoxr)
for (y = 1; y < _yRes - 1; y++, index += 2)
for (x = 1; x < _xRes - 1; x++, index++)
{
// if the cell is a variable
_Acenter[index] = 1.0f;
if (!skip[index])
{
// set the matrix to the Poisson stencil in order
if (!skip[index + 1]) _Acenter[index] += heatConst;
if (!skip[index - 1]) _Acenter[index] += heatConst;
if (!skip[index + _xRes]) _Acenter[index] += heatConst;
if (!skip[index - _xRes]) _Acenter[index] += heatConst;
if (!skip[index + _slabSize]) _Acenter[index] += heatConst;
if (!skip[index - _slabSize]) _Acenter[index] += heatConst;
_residual[index] = b[index] - (_Acenter[index] * field[index] +
field[index - 1] * (skip[index - 1] ? 0.0 : -heatConst) +
field[index + 1] * (skip[index + 1] ? 0.0 : -heatConst) +
field[index - _xRes] * (skip[index - _xRes] ? 0.0 : -heatConst) +
field[index + _xRes] * (skip[index + _xRes] ? 0.0 : -heatConst) +
field[index - _slabSize] * (skip[index - _slabSize] ? 0.0 : -heatConst) +
field[index + _slabSize] * (skip[index + _slabSize] ? 0.0 : -heatConst));
}
else
{
_residual[index] = 0.0f;
}
_residual[index] = b[index] - (_Acenter[index] * field[index] +
field[index - 1] * (skip[index - 1] ? 0.0 : -heatConst) +
field[index + 1] * (skip[index + 1] ? 0.0 : -heatConst) +
field[index - _xRes] * (skip[index - _xRes] ? 0.0 : -heatConst) +
field[index + _xRes] * (skip[index + _xRes] ? 0.0 : -heatConst) +
field[index - _slabSize] * (skip[index - _slabSize] ? 0.0 : -heatConst) +
field[index + _slabSize] * (skip[index + _slabSize] ? 0.0 : -heatConst));
}
else
{
_residual[index] = 0.0f;
}
_direction[index] = _residual[index];
deltaNew += _residual[index] * _residual[index];
}
_direction[index] = _residual[index];
deltaNew += _residual[index] * _residual[index];
}
// While deltaNew > (eps^2) * delta0
const float eps = SOLVER_ACCURACY;
float maxR = 2.0f * eps;
while ((i < _iterations) && (maxR > eps))
{
// q = Ad
float alpha = 0.0f;
// While deltaNew > (eps^2) * delta0
const float eps = SOLVER_ACCURACY;
float maxR = 2.0f * eps;
while ((i < _iterations) && (maxR > eps))
{
// q = Ad
float alpha = 0.0f;
index = _slabSize + _xRes + 1;
for (z = 1; z < _zRes - 1; z++, index += twoxr)
for (y = 1; y < _yRes - 1; y++, index += 2)
for (x = 1; x < _xRes - 1; x++, index++)
{
// if the cell is a variable
if (!skip[index])
{
index = _slabSize + _xRes + 1;
for (z = 1; z < _zRes - 1; z++, index += twoxr)
for (y = 1; y < _yRes - 1; y++, index += 2)
for (x = 1; x < _xRes - 1; x++, index++)
{
// if the cell is a variable
if (!skip[index])
{
_q[index] = (_Acenter[index] * _direction[index] +
_direction[index - 1] * (skip[index - 1] ? 0.0 : -heatConst) +
_direction[index + 1] * (skip[index + 1] ? 0.0 : -heatConst) +
_direction[index - _xRes] * (skip[index - _xRes] ? 0.0 : -heatConst) +
_direction[index + _xRes] * (skip[index + _xRes] ? 0.0 : -heatConst) +
_direction[index - _slabSize] * (skip[index - _slabSize] ? 0.0 : -heatConst) +
_direction[index + _slabSize] * (skip[index + _slabSize] ? 0.0 : -heatConst));
}
else
{
_q[index] = 0.0f;
}
alpha += _direction[index] * _q[index];
}
_q[index] = (_Acenter[index] * _direction[index] +
_direction[index - 1] * (skip[index - 1] ? 0.0 : -heatConst) +
_direction[index + 1] * (skip[index + 1] ? 0.0 : -heatConst) +
_direction[index - _xRes] * (skip[index - _xRes] ? 0.0 : -heatConst) +
_direction[index + _xRes] * (skip[index + _xRes] ? 0.0 : -heatConst) +
_direction[index - _slabSize] * (skip[index - _slabSize] ? 0.0 : -heatConst) +
_direction[index + _slabSize] * (skip[index + _slabSize] ? 0.0 : -heatConst));
}
else
{
_q[index] = 0.0f;
}
alpha += _direction[index] * _q[index];
}
if (fabs(alpha) > 0.0f)
alpha = deltaNew / alpha;
float deltaOld = deltaNew;
deltaNew = 0.0f;
if (fabs(alpha) > 0.0f)
alpha = deltaNew / alpha;
maxR = 0.0f;
float deltaOld = deltaNew;
deltaNew = 0.0f;
index = _slabSize + _xRes + 1;
for (z = 1; z < _zRes - 1; z++, index += twoxr)
for (y = 1; y < _yRes - 1; y++, index += 2)
for (x = 1; x < _xRes - 1; x++, index++)
{
field[index] += alpha * _direction[index];
maxR = 0.0f;
_residual[index] -= alpha * _q[index];
maxR = (_residual[index] > maxR) ? _residual[index] : maxR;
index = _slabSize + _xRes + 1;
for (z = 1; z < _zRes - 1; z++, index += twoxr)
for (y = 1; y < _yRes - 1; y++, index += 2)
for (x = 1; x < _xRes - 1; x++, index++)
{
field[index] += alpha * _direction[index];
deltaNew += _residual[index] * _residual[index];
}
_residual[index] -= alpha * _q[index];
maxR = (_residual[index] > maxR) ? _residual[index] : maxR;
float beta = deltaNew / deltaOld;
deltaNew += _residual[index] * _residual[index];
}
index = _slabSize + _xRes + 1;
for (z = 1; z < _zRes - 1; z++, index += twoxr)
for (y = 1; y < _yRes - 1; y++, index += 2)
for (x = 1; x < _xRes - 1; x++, index++)
_direction[index] = _residual[index] + beta * _direction[index];
float beta = deltaNew / deltaOld;
i++;
}
// cout << i << " iterations converged to " << maxR << endl;
index = _slabSize + _xRes + 1;
for (z = 1; z < _zRes - 1; z++, index += twoxr)
for (y = 1; y < _yRes - 1; y++, index += 2)
for (x = 1; x < _xRes - 1; x++, index++)
_direction[index] = _residual[index] + beta * _direction[index];
if (_residual) delete[] _residual;
if (_direction) delete[] _direction;
if (_q) delete[] _q;
if (_Acenter) delete[] _Acenter;
i++;
}
// cout << i << " iterations converged to " << maxR << endl;
if (_residual) delete[] _residual;
if (_direction) delete[] _direction;
if (_q) delete[] _q;
if (_Acenter) delete[] _Acenter;
}
#define SMOKE_LOOP \
index = _slabSize + _xRes + 1; \
for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes) \
for (y = 1; y < _yRes - 1; y++, index += 2) \
for (x = 1; x < _xRes - 1; x++, index++)
void FLUID_3D::precond_init_diag(float *precond, float* source, unsigned char* skip, size_t index)
{
// if the cell is a variable
float Acenter = 0.0f;
if (!skip[index])
{
// set the matrix to the Poisson stencil in order
if (!skip[index + 1]) Acenter += 1.;
if (!skip[index - 1]) Acenter += 1.;
if (!skip[index + _xRes]) Acenter += 1.;
if (!skip[index - _xRes]) Acenter += 1.;
if (!skip[index + _slabSize]) Acenter += 1.;
if (!skip[index - _slabSize]) Acenter += 1.;
}
// P^-1
if(Acenter < 1.0)
precond[index] = 0.0;
else
precond[index] = 1.0 / Acenter;
}
void FLUID_3D::precond_apply_diag(float *dest, float* source, float *precond, unsigned char* skip, size_t index)
{
dest[index] = source[index] * precond[index];
}
#define SQUARE(a) ((a)*(a))
void FLUID_3D::precond_init_mic(float *precond, float* source, unsigned char* skip, size_t index)
{
const Real tau = 0.97;
const Real sigma = 0.25;
// TODO
}
void FLUID_3D::precond_apply_mic(float *dest, float* source, float *precond, unsigned char* skip, size_t index)
{
// TODO
}
void FLUID_3D::solvePressurePre(float* field, float* b, unsigned char* skip)
{
@@ -190,136 +236,142 @@ void FLUID_3D::solvePressurePre(float* field, float* b, unsigned char* skip)
float deltaNew = 0.0f;
// r = b - Ax
index = _slabSize + _xRes + 1;
for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
for (y = 1; y < _yRes - 1; y++, index += 2)
for (x = 1; x < _xRes - 1; x++, index++)
{
SMOKE_LOOP
{
// r = b - Ax, with x = 0
_residual[index] = b[index];
// init diagonal preconditioner
precond_init_diag(_Precond, field, skip, index);
// p = P^-1 * r
precond_apply_diag(_direction, _residual, _Precond, skip, index);
// _direction[index] = _residual[index] * _Precond[index];
deltaNew += _residual[index] * _direction[index];
}
// While deltaNew > (eps^2) * delta0
const float eps = SOLVER_ACCURACY;
//while ((i < _iterations) && (deltaNew > eps*delta0))
float maxR = 2.0f * eps;
// while (i < _iterations)
while ((i < _iterations) && (maxR > 0.001*eps))
{
float alpha = 0.0f;
SMOKE_LOOP
{
// if the cell is a variable
float Acenter = 0.0f;
if (!skip[index])
{
// set the matrix to the Poisson stencil in order
if (!skip[index + 1]) Acenter += 1.;
if (!skip[index - 1]) Acenter += 1.;
if (!skip[index + _xRes]) Acenter += 1.;
if (!skip[index - _xRes]) Acenter += 1.;
if (!skip[index + _slabSize]) Acenter += 1.;
if (!skip[index - _slabSize]) Acenter += 1.;
// set the matrix to the Poisson stencil in order
if (!skip[index + 1]) Acenter += 1.;
if (!skip[index - 1]) Acenter += 1.;
if (!skip[index + _xRes]) Acenter += 1.;
if (!skip[index - _xRes]) Acenter += 1.;
if (!skip[index + _slabSize]) Acenter += 1.;
if (!skip[index - _slabSize]) Acenter += 1.;
_residual[index] = b[index] - (Acenter * field[index] +
field[index - 1] * (skip[index - 1] ? 0.0 : -1.0f)+
field[index + 1] * (skip[index + 1] ? 0.0 : -1.0f)+
field[index - _xRes] * (skip[index - _xRes] ? 0.0 : -1.0f)+
field[index + _xRes] * (skip[index + _xRes] ? 0.0 : -1.0f)+
field[index - _slabSize] * (skip[index - _slabSize] ? 0.0 : -1.0f)+
field[index + _slabSize] * (skip[index + _slabSize] ? 0.0 : -1.0f) );
_q[index] = Acenter * _direction[index] +
_direction[index - 1] * (skip[index - 1] ? 0.0 : -1.0f) +
_direction[index + 1] * (skip[index + 1] ? 0.0 : -1.0f) +
_direction[index - _xRes] * (skip[index - _xRes] ? 0.0 : -1.0f) +
_direction[index + _xRes] * (skip[index + _xRes] ? 0.0 : -1.0f)+
_direction[index - _slabSize] * (skip[index - _slabSize] ? 0.0 : -1.0f) +
_direction[index + _slabSize] * (skip[index + _slabSize] ? 0.0 : -1.0f);
}
else
{
_residual[index] = 0.0f;
_q[index] = 0.0f;
}
// P^-1
if(Acenter < 1.0)
_Precond[index] = 0.0;
else
_Precond[index] = 1.0 / Acenter;
// p = P^-1 * r
_direction[index] = _residual[index] * _Precond[index];
deltaNew += _residual[index] * _direction[index];
}
// While deltaNew > (eps^2) * delta0
const float eps = SOLVER_ACCURACY;
//while ((i < _iterations) && (deltaNew > eps*delta0))
float maxR = 2.0f * eps;
// while (i < _iterations)
while ((i < _iterations) && (maxR > 0.001*eps))
{
float alpha = 0.0f;
index = _slabSize + _xRes + 1;
for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
for (y = 1; y < _yRes - 1; y++, index += 2)
for (x = 1; x < _xRes - 1; x++, index++)
{
// if the cell is a variable
float Acenter = 0.0f;
if (!skip[index])
{
// set the matrix to the Poisson stencil in order
if (!skip[index + 1]) Acenter += 1.;
if (!skip[index - 1]) Acenter += 1.;
if (!skip[index + _xRes]) Acenter += 1.;
if (!skip[index - _xRes]) Acenter += 1.;
if (!skip[index + _slabSize]) Acenter += 1.;
if (!skip[index - _slabSize]) Acenter += 1.;
_q[index] = Acenter * _direction[index] +
_direction[index - 1] * (skip[index - 1] ? 0.0 : -1.0f) +
_direction[index + 1] * (skip[index + 1] ? 0.0 : -1.0f) +
_direction[index - _xRes] * (skip[index - _xRes] ? 0.0 : -1.0f) +
_direction[index + _xRes] * (skip[index + _xRes] ? 0.0 : -1.0f)+
_direction[index - _slabSize] * (skip[index - _slabSize] ? 0.0 : -1.0f) +
_direction[index + _slabSize] * (skip[index + _slabSize] ? 0.0 : -1.0f);
}
else
{
_q[index] = 0.0f;
}
alpha += _direction[index] * _q[index];
}
if (fabs(alpha) > 0.0f)
alpha = deltaNew / alpha;
float deltaOld = deltaNew;
deltaNew = 0.0f;
maxR = 0.0;
float tmp;
// x = x + alpha * d
index = _slabSize + _xRes + 1;
for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
for (y = 1; y < _yRes - 1; y++, index += 2)
for (x = 1; x < _xRes - 1; x++, index++)
{
field[index] += alpha * _direction[index];
_residual[index] -= alpha * _q[index];
_h[index] = _Precond[index] * _residual[index];
tmp = _residual[index] * _h[index];
deltaNew += tmp;
maxR = (tmp > maxR) ? tmp : maxR;
alpha += _direction[index] * _q[index];
}
// beta = deltaNew / deltaOld
float beta = deltaNew / deltaOld;
if (fabs(alpha) > 0.0f)
alpha = deltaNew / alpha;
// d = h + beta * d
index = _slabSize + _xRes + 1;
for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
for (y = 1; y < _yRes - 1; y++, index += 2)
for (x = 1; x < _xRes - 1; x++, index++)
_direction[index] = _h[index] + beta * _direction[index];
float deltaOld = deltaNew;
deltaNew = 0.0f;
// i = i + 1
i++;
}
// cout << i << " iterations converged to " << sqrt(maxR) << endl;
maxR = 0.0;
float tmp;
// x = x + alpha * d
SMOKE_LOOP
{
field[index] += alpha * _direction[index];
}
if(i % 50)
{
SMOKE_LOOP
{
// if the cell is a variable
float Acenter = 0.0f;
if (!skip[index])
{
// set the matrix to the Poisson stencil in order
if (!skip[index + 1]) Acenter += 1.;
if (!skip[index - 1]) Acenter += 1.;
if (!skip[index + _xRes]) Acenter += 1.;
if (!skip[index - _xRes]) Acenter += 1.;
if (!skip[index + _slabSize]) Acenter += 1.;
if (!skip[index - _slabSize]) Acenter += 1.;
_residual[index] = b[index] - (Acenter * field[index] +
field[index - 1] * (skip[index - 1] ? 0.0 : -1.0f) +
field[index + 1] * (skip[index + 1] ? 0.0 : -1.0f) +
field[index - _xRes] * (skip[index - _xRes] ? 0.0 : -1.0f) +
field[index + _xRes] * (skip[index + _xRes] ? 0.0 : -1.0f)+
field[index - _slabSize] * (skip[index - _slabSize] ? 0.0 : -1.0f) +
field[index + _slabSize] * (skip[index + _slabSize] ? 0.0 : -1.0f) );
}
else
{
_residual[index] = 0.0f;
}
}
}
else
{
SMOKE_LOOP
{
_residual[index] -= alpha * _q[index];
}
}
SMOKE_LOOP
{
// Apply preconditioner
precond_apply_diag(_h, _residual, _Precond, skip, index);
// _h[index] = _Precond[index] * _residual[index];
tmp = _residual[index] * _h[index];
deltaNew += tmp;
maxR = (tmp > maxR) ? tmp : maxR;
}
// beta = deltaNew / deltaOld
float beta = deltaNew / deltaOld;
// d = h + beta * d
SMOKE_LOOP
{
_direction[index] = _h[index] + beta * _direction[index];
}
// i = i + 1
i++;
}
// cout << i << " iterations converged to " << sqrt(maxR) << endl;
if (_h) delete[] _h;
if (_Precond) delete[] _Precond;

View File

@@ -1,6 +1,6 @@
/** \file smoke/intern/FLUID_3D_STATIC.cpp
* \ingroup smoke
*/
* \ingroup smoke
*/
//////////////////////////////////////////////////////////////////////
// This file is part of Wavelet Turbulence.
//
@@ -39,12 +39,12 @@
//////////////////////////////////////////////////////////////////////
/*
void FLUID_3D::addSmokeColumn() {
addSmokeTestCase(_density, _res, 1.0);
// addSmokeTestCase(_zVelocity, _res, 1.0);
addSmokeTestCase(_heat, _res, 1.0);
if (_wTurbulence) {
addSmokeTestCase(_wTurbulence->getDensityBig(), _wTurbulence->getResBig(), 1.0);
}
addSmokeTestCase(_density, _res, 1.0);
// addSmokeTestCase(_zVelocity, _res, 1.0);
addSmokeTestCase(_heat, _res, 1.0);
if (_wTurbulence) {
addSmokeTestCase(_wTurbulence->getDensityBig(), _wTurbulence->getResBig(), 1.0);
}
}
*/
@@ -105,7 +105,7 @@ void FLUID_3D::setNeumannX(float* field, Vec3Int res, int zBegin, int zEnd)
index -= 1;
if(field[index]<0.) field[index] = 0.;
}
}
}
//////////////////////////////////////////////////////////////////////
// set y direction to Neumann boundary conditions
@@ -176,7 +176,7 @@ void FLUID_3D::setNeumannZ(float* field, Vec3Int res, int zBegin, int zEnd)
if(field[index]<0.) field[index] = 0.;
}
}
}
//////////////////////////////////////////////////////////////////////
@@ -229,29 +229,29 @@ void FLUID_3D::setZeroZ(float* field, Vec3Int res, int zBegin, int zEnd)
int index = 0;
if ((zBegin == 0))
for (int y = 0; y < res[1]; y++)
for (int x = 0; x < res[0]; x++, index++)
{
// front slab
field[index] = 0.0f;
}
if (zEnd == res[2])
{
index=0;
int indexx=0;
const int cellsslab = totalCells - slabSize;
for (int y = 0; y < res[1]; y++)
for (int x = 0; x < res[0]; x++, index++)
{
// back slab
indexx = index + cellsslab;
field[indexx] = 0.0f;
// front slab
field[index] = 0.0f;
}
}
}
if (zEnd == res[2])
{
index=0;
int indexx=0;
const int cellsslab = totalCells - slabSize;
for (int y = 0; y < res[1]; y++)
for (int x = 0; x < res[0]; x++, index++)
{
// back slab
indexx = index + cellsslab;
field[indexx] = 0.0f;
}
}
}
//////////////////////////////////////////////////////////////////////
// copy grid boundary
//////////////////////////////////////////////////////////////////////
@@ -294,34 +294,34 @@ void FLUID_3D::copyBorderZ(float* field, Vec3Int res, int zBegin, int zEnd)
int index=0;
if ((zBegin == 0))
for (int y = 0; y < res[1]; y++)
for (int x = 0; x < res[0]; x++, index++)
{
field[index] = field[index + slabSize];
}
for (int y = 0; y < res[1]; y++)
for (int x = 0; x < res[0]; x++, index++)
{
field[index] = field[index + slabSize];
}
if ((zEnd == res[2]))
{
if ((zEnd == res[2]))
{
index=0;
int indexx=0;
const int cellsslab = totalCells - slabSize;
index=0;
int indexx=0;
const int cellsslab = totalCells - slabSize;
for (int y = 0; y < res[1]; y++)
for (int x = 0; x < res[0]; x++, index++)
{
// back slab
indexx = index + cellsslab;
field[indexx] = field[indexx - slabSize];
}
}
for (int y = 0; y < res[1]; y++)
for (int x = 0; x < res[0]; x++, index++)
{
// back slab
indexx = index + cellsslab;
field[indexx] = field[indexx - slabSize];
}
}
}
/////////////////////////////////////////////////////////////////////
// advect field with the semi lagrangian method
//////////////////////////////////////////////////////////////////////
void FLUID_3D::advectFieldSemiLagrange(const float dt, const float* velx, const float* vely, const float* velz,
float* oldField, float* newField, Vec3Int res, int zBegin, int zEnd)
float* oldField, float* newField, Vec3Int res, int zBegin, int zEnd)
{
const int xres = res[0];
const int yres = res[1];
@@ -334,8 +334,8 @@ void FLUID_3D::advectFieldSemiLagrange(const float dt, const float* velx, const
for (int x = 0; x < xres; x++)
{
const int index = x + y * xres + z * xres*yres;
// backtrace
// backtrace
float xTrace = x - dt * velx[index];
float yTrace = y - dt * vely[index];
float zTrace = z - dt * velz[index];
@@ -376,13 +376,13 @@ void FLUID_3D::advectFieldSemiLagrange(const float dt, const float* velx, const
// interpolate
// (indices could be computed once)
newField[index] = u0 * (s0 * (t0 * oldField[i000] +
t1 * oldField[i010]) +
s1 * (t0 * oldField[i100] +
t1 * oldField[i110])) +
t1 * oldField[i010]) +
s1 * (t0 * oldField[i100] +
t1 * oldField[i110])) +
u1 * (s0 * (t0 * oldField[i001] +
t1 * oldField[i011]) +
s1 * (t0 * oldField[i101] +
t1 * oldField[i111]));
t1 * oldField[i011]) +
s1 * (t0 * oldField[i101] +
t1 * oldField[i111]));
}
}
@@ -393,14 +393,14 @@ void FLUID_3D::advectFieldSemiLagrange(const float dt, const float* velx, const
// comments are the pseudocode from selle's paper
//////////////////////////////////////////////////////////////////////
void FLUID_3D::advectFieldMacCormack1(const float dt, const float* xVelocity, const float* yVelocity, const float* zVelocity,
float* oldField, float* tempResult, Vec3Int res, int zBegin, int zEnd)
float* oldField, float* tempResult, Vec3Int res, int zBegin, int zEnd)
{
/*const int sx= res[0];
const int sy= res[1];
const int sz= res[2];
for (int x = 0; x < sx * sy * sz; x++)
phiHatN[x] = phiHatN1[x] = oldField[x];*/ // not needed as all the values are written first
phiHatN[x] = phiHatN1[x] = oldField[x];*/ // not needed as all the values are written first
float*& phiN = oldField;
float*& phiN1 = tempResult;
@@ -414,7 +414,7 @@ void FLUID_3D::advectFieldMacCormack1(const float dt, const float* xVelocity, co
void FLUID_3D::advectFieldMacCormack2(const float dt, const float* xVelocity, const float* yVelocity, const float* zVelocity,
float* oldField, float* newField, float* tempResult, float* temp1, Vec3Int res, const unsigned char* obstacles, int zBegin, int zEnd)
float* oldField, float* newField, float* tempResult, float* temp1, Vec3Int res, const unsigned char* obstacles, int zBegin, int zEnd)
{
float* phiHatN = tempResult;
float* t1 = temp1;
@@ -438,15 +438,15 @@ void FLUID_3D::advectFieldMacCormack2(const float dt, const float* xVelocity, co
phiN1[index] = phiHatN[index] + (phiN[index] - t1[index]) * 0.50f;
//phiN1[index] = phiHatN1[index]; // debug, correction off
}
copyBorderX(phiN1, res, zBegin, zEnd);
copyBorderY(phiN1, res, zBegin, zEnd);
copyBorderZ(phiN1, res, zBegin, zEnd);
copyBorderX(phiN1, res, zBegin, zEnd);
copyBorderY(phiN1, res, zBegin, zEnd);
copyBorderZ(phiN1, res, zBegin, zEnd);
// clamp any newly created extrema
clampExtrema(dt, xVelocity, yVelocity, zVelocity, oldField, newField, res, zBegin, zEnd); // uses wide data from old field and velocities (both are whole)
// clamp any newly created extrema
clampExtrema(dt, xVelocity, yVelocity, zVelocity, oldField, newField, res, zBegin, zEnd); // uses wide data from old field and velocities (both are whole)
// if the error estimate was bad, revert to first order
clampOutsideRays(dt, xVelocity, yVelocity, zVelocity, oldField, newField, res, obstacles, phiHatN, zBegin, zEnd); // phiHatN is only used at cells within thread range, so its ok
// if the error estimate was bad, revert to first order
clampOutsideRays(dt, xVelocity, yVelocity, zVelocity, oldField, newField, res, obstacles, phiHatN, zBegin, zEnd); // phiHatN is only used at cells within thread range, so its ok
}
@@ -455,7 +455,7 @@ void FLUID_3D::advectFieldMacCormack2(const float dt, const float* xVelocity, co
// Clamp the extrema generated by the BFECC error correction
//////////////////////////////////////////////////////////////////////
void FLUID_3D::clampExtrema(const float dt, const float* velx, const float* vely, const float* velz,
float* oldField, float* newField, Vec3Int res, int zBegin, int zEnd)
float* oldField, float* newField, Vec3Int res, int zBegin, int zEnd)
{
const int xres= res[0];
const int yres= res[1];
@@ -539,7 +539,7 @@ void FLUID_3D::clampExtrema(const float dt, const float* velx, const float* vely
// incorrect
//////////////////////////////////////////////////////////////////////
void FLUID_3D::clampOutsideRays(const float dt, const float* velx, const float* vely, const float* velz,
float* oldField, float* newField, Vec3Int res, const unsigned char* obstacles, const float *oldAdvection, int zBegin, int zEnd)
float* oldField, float* newField, Vec3Int res, const unsigned char* obstacles, const float *oldAdvection, int zBegin, int zEnd)
{
const int sx= res[0];
const int sy= res[1];
@@ -657,14 +657,14 @@ void FLUID_3D::clampOutsideRays(const float dt, const float* velx, const float*
// interpolate, (indices could be computed once)
newField[index] = u0 * (s0 * (
t0 * oldField[i000] +
t1 * oldField[i010]) +
s1 * (t0 * oldField[i100] +
t1 * oldField[i110])) +
t0 * oldField[i000] +
t1 * oldField[i010]) +
s1 * (t0 * oldField[i100] +
t1 * oldField[i110])) +
u1 * (s0 * (t0 * oldField[i001] +
t1 * oldField[i011]) +
s1 * (t0 * oldField[i101] +
t1 * oldField[i111]));
t1 * oldField[i011]) +
s1 * (t0 * oldField[i101] +
t1 * oldField[i111]));
}
} // xyz
}

View File

@@ -1,22 +1,22 @@
# common stuff
LDFLAGS_COMMON = -lfftw3 #-lglut -lglu32 -lopengl32 -lz -lpng
CFLAGS_COMMON = -c -Wall -I./ #-I/cygdrive/c/lib/glvu/include -D_WIN32
CC = g++
CFLAGS = ${CFLAGS_COMMON} -O3 -Wno-unused
LDFLAGS = ${LDFLAGS_COMMON}
EXECUTABLE = noiseFFT
SOURCES = noiseFFT.cpp
OBJECTS = $(SOURCES:.cpp=.o)
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(OBJECTS) $(LDFLAGS) -o $@
.cpp.o:
$(CC) $(CFLAGS) $< -o $@
clean:
rm -f *.o $(EXECUTABLE_LOADER) $(EXECUTABLE)
# common stuff
LDFLAGS_COMMON = -lfftw3 #-lglut -lglu32 -lopengl32 -lz -lpng
CFLAGS_COMMON = -c -Wall -I./ #-I/cygdrive/c/lib/glvu/include -D_WIN32
CC = g++
CFLAGS = ${CFLAGS_COMMON} -O3 -Wno-unused
LDFLAGS = ${LDFLAGS_COMMON}
EXECUTABLE = noiseFFT
SOURCES = noiseFFT.cpp
OBJECTS = $(SOURCES:.cpp=.o)
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(OBJECTS) $(LDFLAGS) -o $@
.cpp.o:
$(CC) $(CFLAGS) $< -o $@
clean:
rm -f *.o $(EXECUTABLE_LOADER) $(EXECUTABLE)

View File

@@ -1,23 +1,23 @@
CC = g++
LDFLAGS = -lz -lpng
CFLAGS = -O3 -Wno-unused -c -Wall -I./ -D_WIN32
EXECUTABLE = FLUID_3D
SOURCES = main.cpp FLUID_3D.cpp FLUID_3D_SOLVERS.cpp FLUID_3D_STATIC.cpp SPHERE.cpp WTURBULENCE.cpp
OBJECTS = $(SOURCES:.cpp=.o)
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(OBJECTS) $(LDFLAGS) -o $@
.cpp.o:
$(CC) $(CFLAGS) $< -o $@
SPHERE.o: SPHERE.h
FLUID_3D.o: FLUID_3D.h FLUID_3D.cpp
FLUID_3D_SOLVERS.o: FLUID_3D.h FLUID_3D_SOLVERS.cpp
main.o: FLUID_3D.h FLUID_3D.cpp FLUID_3D_SOLVERS.cpp
clean:
rm -f *.o $(EXECUTABLE_LOADER) $(EXECUTABLE)
CC = g++
LDFLAGS = -lz -lpng
CFLAGS = -O3 -Wno-unused -c -Wall -I./ -D_WIN32
EXECUTABLE = FLUID_3D
SOURCES = main.cpp FLUID_3D.cpp FLUID_3D_SOLVERS.cpp FLUID_3D_STATIC.cpp SPHERE.cpp WTURBULENCE.cpp
OBJECTS = $(SOURCES:.cpp=.o)
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(OBJECTS) $(LDFLAGS) -o $@
.cpp.o:
$(CC) $(CFLAGS) $< -o $@
SPHERE.o: SPHERE.h
FLUID_3D.o: FLUID_3D.h FLUID_3D.cpp
FLUID_3D_SOLVERS.o: FLUID_3D.h FLUID_3D_SOLVERS.cpp
main.o: FLUID_3D.h FLUID_3D.cpp FLUID_3D_SOLVERS.cpp
clean:
rm -f *.o $(EXECUTABLE_LOADER) $(EXECUTABLE)

View File

@@ -1,23 +1,23 @@
CC = g++
LDFLAGS = -lz -lpng -fopenmp -lgomp
CFLAGS = -c -Wall -I./ -fopenmp -DPARALLEL=1 -O3 -Wno-unused
EXECUTABLE = FLUID_3D
SOURCES = main.cpp FLUID_3D.cpp FLUID_3D_SOLVERS.cpp FLUID_3D_STATIC.cpp SPHERE.cpp WTURBULENCE.cpp
OBJECTS = $(SOURCES:.cpp=.o)
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(OBJECTS) $(LDFLAGS) -o $@
.cpp.o:
$(CC) $(CFLAGS) $< -o $@
SPHERE.o: SPHERE.h
FLUID_3D.o: FLUID_3D.h FLUID_3D.cpp
FLUID_3D_SOLVERS.o: FLUID_3D.h FLUID_3D_SOLVERS.cpp
main.o: FLUID_3D.h FLUID_3D.cpp FLUID_3D_SOLVERS.cpp
clean:
rm -f *.o $(EXECUTABLE_LOADER) $(EXECUTABLE)
CC = g++
LDFLAGS = -lz -lpng -fopenmp -lgomp
CFLAGS = -c -Wall -I./ -fopenmp -DPARALLEL=1 -O3 -Wno-unused
EXECUTABLE = FLUID_3D
SOURCES = main.cpp FLUID_3D.cpp FLUID_3D_SOLVERS.cpp FLUID_3D_STATIC.cpp SPHERE.cpp WTURBULENCE.cpp
OBJECTS = $(SOURCES:.cpp=.o)
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(OBJECTS) $(LDFLAGS) -o $@
.cpp.o:
$(CC) $(CFLAGS) $< -o $@
SPHERE.o: SPHERE.h
FLUID_3D.o: FLUID_3D.h FLUID_3D.cpp
FLUID_3D_SOLVERS.o: FLUID_3D.h FLUID_3D_SOLVERS.cpp
main.o: FLUID_3D.h FLUID_3D.cpp FLUID_3D_SOLVERS.cpp
clean:
rm -f *.o $(EXECUTABLE_LOADER) $(EXECUTABLE)

View File

@@ -1,35 +1,35 @@
CC = g++
# uncomment the other two OPENMP_... lines, if your gcc supports OpenMP
#OPENMP_FLAGS = -fopenmp -DPARALLEL=1 -I/opt/gcc-4.3/usr/local/include
#OPENMPLD_FLAGS = -fopenmp -lgomp -I/opt/gcc-4.3/usr/local/lib
OPENMP_FLAGS =
OPENMPLD_FLAGS =
# assumes MacPorts libpng installation
PNG_INCLUDE = -I/opt/local/include
PNG_LIBS = -I/opt/local/lib
LDFLAGS = $(PNG_LIBS)-lz -lpng $(OPENMPLD_FLAGS)
CFLAGS = -c -Wall -I./ $(PNG_INCLUDE) $(OPENMP_FLAGS) -O3 -Wno-unused
EXECUTABLE = FLUID_3D
SOURCES = main.cpp FLUID_3D.cpp FLUID_3D_SOLVERS.cpp FLUID_3D_STATIC.cpp SPHERE.cpp WTURBULENCE.cpp
OBJECTS = $(SOURCES:.cpp=.o)
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(OBJECTS) $(LDFLAGS) -o $@
.cpp.o:
$(CC) $(CFLAGS) $< -o $@
SPHERE.o: SPHERE.h
FLUID_3D.o: FLUID_3D.h FLUID_3D.cpp
FLUID_3D_SOLVERS.o: FLUID_3D.h FLUID_3D_SOLVERS.cpp
main.o: FLUID_3D.h FLUID_3D.cpp FLUID_3D_SOLVERS.cpp
clean:
rm -f *.o $(EXECUTABLE_LOADER) $(EXECUTABLE)
CC = g++
# uncomment the other two OPENMP_... lines, if your gcc supports OpenMP
#OPENMP_FLAGS = -fopenmp -DPARALLEL=1 -I/opt/gcc-4.3/usr/local/include
#OPENMPLD_FLAGS = -fopenmp -lgomp -I/opt/gcc-4.3/usr/local/lib
OPENMP_FLAGS =
OPENMPLD_FLAGS =
# assumes MacPorts libpng installation
PNG_INCLUDE = -I/opt/local/include
PNG_LIBS = -I/opt/local/lib
LDFLAGS = $(PNG_LIBS)-lz -lpng $(OPENMPLD_FLAGS)
CFLAGS = -c -Wall -I./ $(PNG_INCLUDE) $(OPENMP_FLAGS) -O3 -Wno-unused
EXECUTABLE = FLUID_3D
SOURCES = main.cpp FLUID_3D.cpp FLUID_3D_SOLVERS.cpp FLUID_3D_STATIC.cpp SPHERE.cpp WTURBULENCE.cpp
OBJECTS = $(SOURCES:.cpp=.o)
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(OBJECTS) $(LDFLAGS) -o $@
.cpp.o:
$(CC) $(CFLAGS) $< -o $@
SPHERE.o: SPHERE.h
FLUID_3D.o: FLUID_3D.h FLUID_3D.cpp
FLUID_3D_SOLVERS.o: FLUID_3D.h FLUID_3D_SOLVERS.cpp
main.o: FLUID_3D.h FLUID_3D.cpp FLUID_3D_SOLVERS.cpp
clean:
rm -f *.o $(EXECUTABLE_LOADER) $(EXECUTABLE)

View File

@@ -215,6 +215,11 @@ extern "C" void smoke_turbulence_export(WTURBULENCE *wt, float **dens, float **d
*tcw = wt->_tcW;
}
extern "C" float *smoke_get_pressure(FLUID_3D *fluid)
{
return fluid->_pressure;
}
extern "C" float *smoke_get_density(FLUID_3D *fluid)
{
return fluid->_density;

View File

@@ -103,7 +103,7 @@ static void tend ( void )
{
QueryPerformanceCounter ( &liCurrentTime );
}
static double UNUSED_FUNCTION(tval)( void )
static double tval( void )
{
return ((double)( (liCurrentTime.QuadPart - liStartTime.QuadPart)* (double)1000.0/(double)liFrequency.QuadPart ));
}
@@ -120,7 +120,7 @@ static void tend ( void )
gettimeofday ( &_tend,&tz );
}
static double UNUSED_FUNCTION(tval)( void )
static double tval( void )
{
double t1, t2;
t1 = ( double ) _tstart.tv_sec*1000 + ( double ) _tstart.tv_usec/ ( 1000 );
@@ -140,9 +140,7 @@ struct SmokeModifierData;
#define DT_DEFAULT 0.1f
/* forward declerations */
static void calcTriangleDivs(Object *ob, MVert *verts, int numverts, MFace *tris, int numfaces, int numtris, int **tridivs, float cell_len);
static void get_cell(const float p0[3], const int res[3], float dx, const float pos[3], int cell[3], int correct);
static void fill_scs_points(Object *ob, DerivedMesh *dm, SmokeCollSettings *scs);
#else /* WITH_SMOKE */
@@ -280,444 +278,19 @@ static int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene,
}
else if((smd->type & MOD_SMOKE_TYPE_COLL))
{
// todo: delete this when loading colls work -dg
if(!smd->coll)
{
smokeModifier_createType(smd);
}
if(!smd->coll->points)
{
// init collision points
SmokeCollSettings *scs = smd->coll;
smd->time = scene->r.cfra;
smd->time = scene->r.cfra;
// copy obmat
copy_m4_m4(scs->mat, ob->obmat);
copy_m4_m4(scs->mat_old, ob->obmat);
DM_ensure_tessface(dm);
fill_scs_points(ob, dm, scs);
}
if(!smd->coll->bvhtree)
{
smd->coll->bvhtree = NULL; // bvhtree_build_from_smoke ( ob->obmat, dm->getTessFaceArray(dm), dm->getNumTessFaces(dm), dm->getVertArray(dm), dm->getNumVerts(dm), 0.0 );
}
return 1;
}
return 2;
}
static void fill_scs_points(Object *ob, DerivedMesh *dm, SmokeCollSettings *scs)
{
MVert *mvert = dm->getVertArray(dm);
MFace *mface = dm->getTessFaceArray(dm);
int i = 0, divs = 0;
// DG TODO: need to do this dynamically according to the domain object!
float cell_len = scs->dx;
int newdivs = 0;
int quads = 0, facecounter = 0;
// count quads
for(i = 0; i < dm->getNumTessFaces(dm); i++)
{
if(mface[i].v4)
quads++;
}
scs->numtris = dm->getNumTessFaces(dm) + quads;
scs->tridivs = NULL;
calcTriangleDivs(ob, mvert, dm->getNumVerts(dm), mface, dm->getNumTessFaces(dm), scs->numtris, &(scs->tridivs), cell_len);
// count triangle divisions
for(i = 0; i < dm->getNumTessFaces(dm) + quads; i++)
{
divs += (scs->tridivs[3 * i] + 1) * (scs->tridivs[3 * i + 1] + 1) * (scs->tridivs[3 * i + 2] + 1);
}
scs->points = MEM_callocN(sizeof(float) * (dm->getNumVerts(dm) + divs) * 3, "SmokeCollPoints");
scs->points_old = MEM_callocN(sizeof(float) * (dm->getNumVerts(dm) + divs) * 3, "SmokeCollPointsOld");
for(i = 0; i < dm->getNumVerts(dm); i++)
{
float tmpvec[3];
copy_v3_v3(tmpvec, mvert[i].co);
// mul_m4_v3(ob->obmat, tmpvec); // DG: use local coordinates, we save MAT anyway
copy_v3_v3(&scs->points[i * 3], tmpvec);
}
for(i = 0, facecounter = 0; i < dm->getNumTessFaces(dm); i++)
{
int again = 0;
do
{
int j, k;
int divs1 = scs->tridivs[3 * facecounter + 0];
int divs2 = scs->tridivs[3 * facecounter + 1];
//int divs3 = scs->tridivs[3 * facecounter + 2];
float side1[3], side2[3], trinormorg[3], trinorm[3];
if(again == 1 && mface[i].v4)
{
sub_v3_v3v3(side1, mvert[ mface[i].v3 ].co, mvert[ mface[i].v1 ].co);
sub_v3_v3v3(side2, mvert[ mface[i].v4 ].co, mvert[ mface[i].v1 ].co);
}
else {
sub_v3_v3v3(side1, mvert[ mface[i].v2 ].co, mvert[ mface[i].v1 ].co);
sub_v3_v3v3(side2, mvert[ mface[i].v3 ].co, mvert[ mface[i].v1 ].co);
}
cross_v3_v3v3(trinormorg, side1, side2);
normalize_v3(trinormorg);
copy_v3_v3(trinorm, trinormorg);
mul_v3_fl(trinorm, 0.25 * cell_len);
for(j = 0; j <= divs1; j++)
{
for(k = 0; k <= divs2; k++)
{
float p1[3], p2[3], p3[3], p[3]={0,0,0};
const float uf = (float)(j + TRI_UVOFFSET) / (float)(divs1 + 0.0);
const float vf = (float)(k + TRI_UVOFFSET) / (float)(divs2 + 0.0);
float tmpvec[3];
if(uf+vf > 1.0)
{
// printf("bigger - divs1: %d, divs2: %d\n", divs1, divs2);
continue;
}
copy_v3_v3(p1, mvert[ mface[i].v1 ].co);
if(again == 1 && mface[i].v4)
{
copy_v3_v3(p2, mvert[ mface[i].v3 ].co);
copy_v3_v3(p3, mvert[ mface[i].v4 ].co);
}
else {
copy_v3_v3(p2, mvert[ mface[i].v2 ].co);
copy_v3_v3(p3, mvert[ mface[i].v3 ].co);
}
mul_v3_fl(p1, (1.0-uf-vf));
mul_v3_fl(p2, uf);
mul_v3_fl(p3, vf);
add_v3_v3v3(p, p1, p2);
add_v3_v3(p, p3);
if(newdivs > divs)
printf("mem problem\n");
// mMovPoints.push_back(p + trinorm);
add_v3_v3v3(tmpvec, p, trinorm);
// mul_m4_v3(ob->obmat, tmpvec); // DG: use local coordinates, we save MAT anyway
copy_v3_v3(&scs->points[3 * (dm->getNumVerts(dm) + newdivs)], tmpvec);
newdivs++;
if(newdivs > divs)
printf("mem problem\n");
// mMovPoints.push_back(p - trinorm);
copy_v3_v3(tmpvec, p);
sub_v3_v3(tmpvec, trinorm);
// mul_m4_v3(ob->obmat, tmpvec); // DG: use local coordinates, we save MAT anyway
copy_v3_v3(&scs->points[3 * (dm->getNumVerts(dm) + newdivs)], tmpvec);
newdivs++;
}
}
if(again == 0 && mface[i].v4)
again++;
else
again = 0;
facecounter++;
} while(again!=0);
}
scs->numverts = dm->getNumVerts(dm);
// DG TODO: also save triangle count?
scs->numpoints = dm->getNumVerts(dm) + newdivs;
for(i = 0; i < scs->numpoints * 3; i++)
{
scs->points_old[i] = scs->points[i];
}
}
static void fill_scs_points_anim(Object *UNUSED(ob), DerivedMesh *dm, SmokeCollSettings *scs)
{
MVert *mvert = dm->getVertArray(dm);
MFace *mface = dm->getTessFaceArray(dm);
int quads = 0, numtris = 0, facecounter = 0;
unsigned int i = 0;
int divs = 0, newdivs = 0;
// DG TODO: need to do this dynamically according to the domain object!
float cell_len = scs->dx;
// count quads
for(i = 0; i < dm->getNumTessFaces(dm); i++)
{
if(mface[i].v4)
quads++;
}
numtris = dm->getNumTessFaces(dm) + quads;
// check if mesh changed topology
if(scs->numtris != numtris)
return;
if(scs->numverts != dm->getNumVerts(dm))
return;
// update new positions
for(i = 0; i < dm->getNumVerts(dm); i++)
{
float tmpvec[3];
copy_v3_v3(tmpvec, mvert[i].co);
copy_v3_v3(&scs->points[i * 3], tmpvec);
}
// for every triangle // update div points
for(i = 0, facecounter = 0; i < dm->getNumTessFaces(dm); i++)
{
int again = 0;
do
{
int j, k;
int divs1 = scs->tridivs[3 * facecounter + 0];
int divs2 = scs->tridivs[3 * facecounter + 1];
float srcside1[3], srcside2[3], destside1[3], destside2[3], src_trinormorg[3], dest_trinormorg[3], src_trinorm[3], dest_trinorm[3];
if(again == 1 && mface[i].v4)
{
sub_v3_v3v3(srcside1, &scs->points_old[mface[i].v3 * 3], &scs->points_old[mface[i].v1 * 3]);
sub_v3_v3v3(destside1, &scs->points[mface[i].v3 * 3], &scs->points[mface[i].v1 * 3]);
sub_v3_v3v3(srcside2, &scs->points_old[mface[i].v4 * 3], &scs->points_old[mface[i].v1 * 3]);
sub_v3_v3v3(destside2, &scs->points[mface[i].v4 * 3], &scs->points[mface[i].v1 * 3]);
}
else {
sub_v3_v3v3(srcside1, &scs->points_old[mface[i].v2 * 3], &scs->points_old[mface[i].v1 * 3]);
sub_v3_v3v3(destside1, &scs->points[mface[i].v2 * 3], &scs->points[mface[i].v1 * 3]);
sub_v3_v3v3(srcside2, &scs->points_old[mface[i].v3 * 3], &scs->points_old[mface[i].v1 * 3]);
sub_v3_v3v3(destside2, &scs->points[mface[i].v3 * 3], &scs->points[mface[i].v1 * 3]);
}
cross_v3_v3v3(src_trinormorg, srcside1, srcside2);
cross_v3_v3v3(dest_trinormorg, destside1, destside2);
normalize_v3(src_trinormorg);
normalize_v3(dest_trinormorg);
copy_v3_v3(src_trinorm, src_trinormorg);
copy_v3_v3(dest_trinorm, dest_trinormorg);
mul_v3_fl(src_trinorm, 0.25 * cell_len);
mul_v3_fl(dest_trinorm, 0.25 * cell_len);
for(j = 0; j <= divs1; j++)
{
for(k = 0; k <= divs2; k++)
{
float src_p1[3], src_p2[3], src_p3[3], src_p[3]={0,0,0};
float dest_p1[3], dest_p2[3], dest_p3[3], dest_p[3]={0,0,0};
const float uf = (float)(j + TRI_UVOFFSET) / (float)(divs1 + 0.0);
const float vf = (float)(k + TRI_UVOFFSET) / (float)(divs2 + 0.0);
float src_tmpvec[3], dest_tmpvec[3];
if(uf+vf > 1.0)
{
// printf("bigger - divs1: %d, divs2: %d\n", divs1, divs2);
continue;
}
copy_v3_v3(src_p1, &scs->points_old[mface[i].v1 * 3]);
copy_v3_v3(dest_p1, &scs->points[mface[i].v1 * 3]);
if(again == 1 && mface[i].v4)
{
copy_v3_v3(src_p2, &scs->points_old[mface[i].v3 * 3]);
copy_v3_v3(dest_p2, &scs->points[mface[i].v3 * 3]);
copy_v3_v3(src_p3,&scs->points_old[mface[i].v4 * 3]);
copy_v3_v3(dest_p3, &scs->points[mface[i].v4 * 3]);
}
else {
copy_v3_v3(src_p2, &scs->points_old[mface[i].v2 * 3]);
copy_v3_v3(dest_p2, &scs->points[mface[i].v2 * 3]);
copy_v3_v3(src_p3, &scs->points_old[mface[i].v3 * 3]);
copy_v3_v3(dest_p3, &scs->points[mface[i].v3 * 3]);
}
mul_v3_fl(src_p1, (1.0-uf-vf));
mul_v3_fl(dest_p1, (1.0-uf-vf));
mul_v3_fl(src_p2, uf);
mul_v3_fl(dest_p2, uf);
mul_v3_fl(src_p3, vf);
mul_v3_fl(dest_p3, vf);
add_v3_v3v3(src_p, src_p1, src_p2);
add_v3_v3v3(dest_p, dest_p1, dest_p2);
add_v3_v3(src_p, src_p3);
add_v3_v3(dest_p, dest_p3);
if(newdivs > divs)
printf("mem problem\n");
// mMovPoints.push_back(p + trinorm);
add_v3_v3v3(src_tmpvec, src_p, src_trinorm);
add_v3_v3v3(dest_tmpvec, dest_p, dest_trinorm);
// mul_m4_v3(ob->obmat, tmpvec); // DG: use local coordinates, we save MAT anyway
copy_v3_v3(&scs->points_old[3 * (dm->getNumVerts(dm) + newdivs)], src_tmpvec);
copy_v3_v3(&scs->points[3 * (dm->getNumVerts(dm) + newdivs)], dest_tmpvec);
newdivs++;
if(newdivs > divs)
printf("mem problem\n");
// mMovPoints.push_back(p - trinorm);
copy_v3_v3(src_tmpvec, src_p);
copy_v3_v3(dest_tmpvec, dest_p);
sub_v3_v3(src_tmpvec, src_trinorm);
sub_v3_v3(dest_tmpvec, dest_trinorm);
// mul_m4_v3(ob->obmat, tmpvec); // DG: use local coordinates, we save MAT anyway
copy_v3_v3(&scs->points_old[3 * (dm->getNumVerts(dm) + newdivs)], src_tmpvec);
copy_v3_v3(&scs->points[3 * (dm->getNumVerts(dm) + newdivs)], dest_tmpvec);
newdivs++;
}
}
if(again == 0 && mface[i].v4)
again++;
else
again = 0;
facecounter++;
} while(again!=0);
}
// scs->numpoints = dm->getNumVerts(dm) + newdivs;
}
/*! init triangle divisions */
static void calcTriangleDivs(Object *ob, MVert *verts, int UNUSED(numverts), MFace *faces, int numfaces, int numtris, int **tridivs, float cell_len)
{
// mTriangleDivs1.resize( faces.size() );
// mTriangleDivs2.resize( faces.size() );
// mTriangleDivs3.resize( faces.size() );
size_t i = 0, facecounter = 0;
float maxscale[3] = {1,1,1}; // = channelFindMaxVf(mcScale); get max scale value
float maxpart = ABS(maxscale[0]);
float scaleFac = 0;
float fsTri = 0;
if(ABS(maxscale[1])>maxpart) maxpart = ABS(maxscale[1]);
if(ABS(maxscale[2])>maxpart) maxpart = ABS(maxscale[2]);
scaleFac = 1.0 / maxpart;
// featureSize = mLevel[mMaxRefine].nodeSize
fsTri = cell_len * 0.75 * scaleFac; // fsTri = cell_len * 0.9;
if(*tridivs)
MEM_freeN(*tridivs);
*tridivs = MEM_callocN(sizeof(int) * numtris * 3, "Smoke_Tridivs");
for(i = 0, facecounter = 0; i < numfaces; i++)
{
float p0[3], p1[3], p2[3];
float side1[3];
float side2[3];
float side3[3];
int divs1=0, divs2=0, divs3=0;
copy_v3_v3(p0, verts[faces[i].v1].co);
mul_m4_v3(ob->obmat, p0);
copy_v3_v3(p1, verts[faces[i].v2].co);
mul_m4_v3(ob->obmat, p1);
copy_v3_v3(p2, verts[faces[i].v3].co);
mul_m4_v3(ob->obmat, p2);
sub_v3_v3v3(side1, p1, p0);
sub_v3_v3v3(side2, p2, p0);
sub_v3_v3v3(side3, p1, p2);
if(dot_v3v3(side1, side1) > fsTri*fsTri)
{
float tmp = normalize_v3(side1);
divs1 = (int)ceil(tmp/fsTri);
}
if(dot_v3v3(side2, side2) > fsTri*fsTri)
{
float tmp = normalize_v3(side2);
divs2 = (int)ceil(tmp/fsTri);
/*
// debug
if(i==0)
printf("b tmp: %f, fsTri: %f, divs2: %d\n", tmp, fsTri, divs2);
*/
}
(*tridivs)[3 * facecounter + 0] = divs1;
(*tridivs)[3 * facecounter + 1] = divs2;
(*tridivs)[3 * facecounter + 2] = divs3;
// TODO quad case
if(faces[i].v4)
{
divs1=0, divs2=0, divs3=0;
facecounter++;
copy_v3_v3(p0, verts[faces[i].v3].co);
mul_m4_v3(ob->obmat, p0);
copy_v3_v3(p1, verts[faces[i].v4].co);
mul_m4_v3(ob->obmat, p1);
copy_v3_v3(p2, verts[faces[i].v1].co);
mul_m4_v3(ob->obmat, p2);
sub_v3_v3v3(side1, p1, p0);
sub_v3_v3v3(side2, p2, p0);
sub_v3_v3v3(side3, p1, p2);
if(dot_v3v3(side1, side1) > fsTri*fsTri)
{
float tmp = normalize_v3(side1);
divs1 = (int)ceil(tmp/fsTri);
}
if(dot_v3v3(side2, side2) > fsTri*fsTri)
{
float tmp = normalize_v3(side2);
divs2 = (int)ceil(tmp/fsTri);
}
(*tridivs)[3 * facecounter + 0] = divs1;
(*tridivs)[3 * facecounter + 1] = divs2;
(*tridivs)[3 * facecounter + 2] = divs3;
}
facecounter++;
}
}
#endif /* WITH_SMOKE */
static void smokeModifier_freeDomain(SmokeModifierData *smd)
@@ -769,36 +342,18 @@ static void smokeModifier_freeCollision(SmokeModifierData *smd)
{
SmokeCollSettings *scs = smd->coll;
if(scs->numpoints)
if(scs->numverts)
{
if(scs->points)
if(scs->verts_old)
{
MEM_freeN(scs->points);
scs->points = NULL;
}
if(scs->points_old)
{
MEM_freeN(scs->points_old);
scs->points_old = NULL;
}
if(scs->tridivs)
{
MEM_freeN(scs->tridivs);
scs->tridivs = NULL;
MEM_freeN(scs->verts_old);
scs->verts_old = NULL;
}
}
if(scs->bvhtree)
{
BLI_bvhtree_free(scs->bvhtree);
scs->bvhtree = NULL;
}
#ifdef USE_SMOKE_COLLISION_DM
if(smd->coll->dm)
smd->coll->dm->release(smd->coll->dm);
smd->coll->dm = NULL;
#endif
MEM_freeN(smd->coll);
smd->coll = NULL;
@@ -851,21 +406,10 @@ void smokeModifier_reset(struct SmokeModifierData *smd)
{
SmokeCollSettings *scs = smd->coll;
if(scs->numpoints && scs->points)
if(scs->numverts && scs->verts_old)
{
MEM_freeN(scs->points);
scs->points = NULL;
if(scs->points_old)
{
MEM_freeN(scs->points_old);
scs->points_old = NULL;
}
if(scs->tridivs)
{
MEM_freeN(scs->tridivs);
scs->tridivs = NULL;
}
MEM_freeN(scs->verts_old);
scs->verts_old = NULL;
}
}
}
@@ -950,15 +494,10 @@ void smokeModifier_createType(struct SmokeModifierData *smd)
smd->coll = MEM_callocN(sizeof(SmokeCollSettings), "SmokeColl");
smd->coll->smd = smd;
smd->coll->points = NULL;
smd->coll->points_old = NULL;
smd->coll->tridivs = NULL;
smd->coll->vel = NULL;
smd->coll->numpoints = 0;
smd->coll->numtris = 0;
smd->coll->bvhtree = NULL;
smd->coll->verts_old = NULL;
smd->coll->numverts = 0;
smd->coll->type = 0; // static obstacle
smd->coll->dx = 1.0f / 50.0f;
smd->coll->dm = NULL;
#ifdef USE_SMOKE_COLLISION_DM
smd->coll->dm = NULL;
@@ -1078,6 +617,153 @@ static void smoke_calc_domain(Scene *UNUSED(scene), Object *UNUSED(ob), SmokeMod
#endif
}
static void obstacles_from_derivedmesh(Object *coll_ob, SmokeDomainSettings *sds, SmokeCollSettings *scs, unsigned char *obstacle_map, float *velocityX, float *velocityY, float *velocityZ, float dt)
{
if (!scs->dm) return;
{
DerivedMesh *dm = NULL;
MDeformVert *dvert = NULL;
MVert *mvert = NULL;
MFace *mface = NULL;
BVHTreeFromMesh treeData = {0};
int numverts, i, z;
int *res = sds->res;
float surface_distance = 0.6;
float *vert_vel = NULL;
int has_velocity = 0;
tstart();
dm = CDDM_copy(scs->dm);
CDDM_calc_normals(dm);
mvert = dm->getVertArray(dm);
mface = dm->getTessFaceArray(dm);
numverts = dm->getNumVerts(dm);
dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
// DG TODO
// if(scs->type > SM_COLL_STATIC)
// if line above is used, the code is in trouble if the object moves but is declared as "does not move"
// if (sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY)
{
vert_vel = MEM_callocN(sizeof(float) * numverts * 3, "smoke_obs_velocity");
if (scs->numverts != numverts || !scs->verts_old) {
if (scs->verts_old) MEM_freeN(scs->verts_old);
scs->verts_old = MEM_callocN(sizeof(float) * numverts * 3, "smoke_obs_verts_old");
scs->numverts = numverts;
}
else {
has_velocity = 1;
}
}
/* Transform collider vertices to
* domain grid space for fast lookups */
for (i = 0; i < numverts; i++) {
float n[3];
/* vert pos */
mul_m4_v3(coll_ob->obmat, mvert[i].co);
sub_v3_v3(mvert[i].co, sds->p0);
mul_v3_fl(mvert[i].co, (1.0f / sds->dx) / sds->scale);
/* vert normal */
normal_short_to_float_v3(n, mvert[i].no);
mul_mat3_m4_v3(coll_ob->obmat, n);
normalize_v3(n);
normal_float_to_short_v3(mvert[i].no, n);
/* vert velocity */
// DG TODO
// if (sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY)
{
if (has_velocity)
{
sub_v3_v3v3(&vert_vel[i*3], mvert[i].co, &scs->verts_old[i*3]);
mul_v3_fl(&vert_vel[i*3], sds->dx/dt);
}
copy_v3_v3(&scs->verts_old[i*3], mvert[i].co);
}
}
if (bvhtree_from_mesh_faces(&treeData, dm, 0.0f, 4, 6)) {
#pragma omp parallel for schedule(static)
for (z = 0; z < res[2]; z++) {
int x,y;
for (x = 0; x < res[0]; x++)
for (y = 0; y < res[1]; y++) {
int index = x + y*res[0] + z*res[0]*res[1];
float ray_start[3] = {(float)x + 0.5f, (float)y + 0.5f, (float)z + 0.5f};
float ray_dir[3] = {1.0f, 0.0f, 0.0f};
BVHTreeRayHit hit = {0};
BVHTreeNearest nearest = {0};
hit.index = -1;
hit.dist = 9999;
nearest.index = -1;
nearest.dist = surface_distance * surface_distance; /* find_nearest uses squared distance */
/* find the nearest point on the mesh */
if (BLI_bvhtree_find_nearest(treeData.tree, ray_start, &nearest, treeData.nearest_callback, &treeData) != -1) {
float weights[4];
int v1, v2, v3, f_index = nearest.index;
float n1[3], n2[3], n3[3], hit_normal[3];
/* calculate barycentric weights for nearest point */
v1 = mface[f_index].v1;
v2 = (nearest.flags & BVH_ONQUAD) ? mface[f_index].v3 : mface[f_index].v2;
v3 = (nearest.flags & BVH_ONQUAD) ? mface[f_index].v4 : mface[f_index].v3;
interp_weights_face_v3(weights, mvert[v1].co, mvert[v2].co, mvert[v3].co, NULL, nearest.co);
// DG TODO
// if(sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY)
if(has_velocity)
{
/* interpolate vertex normal vectors to get nearest point normal */
normal_short_to_float_v3(n1, mvert[v1].no);
normal_short_to_float_v3(n2, mvert[v2].no);
normal_short_to_float_v3(n3, mvert[v3].no);
interp_v3_v3v3v3(hit_normal, n1, n2, n3, weights);
normalize_v3(hit_normal);
/* apply object velocity */
{
float hit_vel[3];
interp_v3_v3v3v3(hit_vel, &vert_vel[v1*3], &vert_vel[v2*3], &vert_vel[v3*3], weights);
velocityX[index] += hit_vel[0];
velocityY[index] += hit_vel[1];
velocityZ[index] += hit_vel[2];
}
}
/* tag obstacle cells */
obstacle_map[index] = 1;
if(has_velocity)
obstacle_map[index] |= 8;
}
}
}
}
/* free bvh tree */
free_bvhtree_from_mesh(&treeData);
dm->release(dm);
if (vert_vel) MEM_freeN(vert_vel);
tend();
printf ( "Time: %f\n\n", ( float ) tval() );
}
}
/* Animated obstacles: dx_step = ((x_new - x_old) / totalsteps) * substep */
static void update_obstacles(Scene *scene, Object *ob, SmokeDomainSettings *sds, float dt, int substep, int totalsteps)
{
@@ -1092,7 +778,7 @@ static void update_obstacles(Scene *scene, Object *ob, SmokeDomainSettings *sds,
float *velxOrig = smoke_get_velocity_x(sds->fluid);
float *velyOrig = smoke_get_velocity_y(sds->fluid);
float *velzOrig = smoke_get_velocity_z(sds->fluid);
// float *density = smoke_get_density(sds->fluid);
float *density = smoke_get_density(sds->fluid);
unsigned int z;
smoke_get_ob_velocity(sds->fluid, &velx, &vely, &velz);
@@ -1100,15 +786,6 @@ static void update_obstacles(Scene *scene, Object *ob, SmokeDomainSettings *sds,
// TODO: delete old obstacle flags
for(z = 0; z < sds->res[0] * sds->res[1] * sds->res[2]; z++)
{
if(obstacles[z])
{
// density[z] = 0;
velxOrig[z] = 0;
velyOrig[z] = 0;
velzOrig[z] = 0;
}
if(obstacles[z] & 8) // Do not delete static obstacles
{
obstacles[z] = 0;
@@ -1119,6 +796,7 @@ static void update_obstacles(Scene *scene, Object *ob, SmokeDomainSettings *sds,
velz[z] = 0;
}
collobjs = get_collisionobjects(scene, ob, sds->coll_group, &numcollobj, eModifierType_Smoke);
// update obstacle tags in cells
@@ -1129,94 +807,29 @@ static void update_obstacles(Scene *scene, Object *ob, SmokeDomainSettings *sds,
// DG TODO: check if modifier is active?
if((smd2->type & MOD_SMOKE_TYPE_COLL) && smd2->coll && smd2->coll->points && smd2->coll->points_old)
if((smd2->type & MOD_SMOKE_TYPE_COLL) && smd2->coll)
{
SmokeCollSettings *scs = smd2->coll;
unsigned int i;
/*
// DG TODO: support static cobstacles, but basicly we could even support static + rigid with one set of code
if(scs->type > SM_COLL_STATIC)
*/
/* Handle collisions */
for(i = 0; i < scs->numpoints; i++)
{
// 1. get corresponding cell
int cell[3];
float pos[3], oldpos[3], vel[3];
float cPos[3], cOldpos[3]; /* current position in substeps */
int badcell = 0;
size_t index;
int j;
// translate local points into global positions
copy_v3_v3(cPos, &scs->points[3 * i]);
mul_m4_v3(scs->mat, cPos);
copy_v3_v3(pos, cPos);
copy_v3_v3(cOldpos, &scs->points_old[3 * i]);
mul_m4_v3(scs->mat_old, cOldpos);
copy_v3_v3(oldpos, cOldpos);
/* support for rigid bodies, armatures etc */
{
float tmp[3];
/* x_current = x_old + (x_new - x_old) * step_current / steps_total */
float mulStep = (float)(((float)substep) / ((float)totalsteps));
sub_v3_v3v3(tmp, cPos, cOldpos);
mul_v3_fl(tmp, mulStep);
add_v3_v3(cOldpos, tmp);
}
sub_v3_v3v3(vel, pos, oldpos);
/* Scale velocity to incorperate the object movement during this step */
mul_v3_fl(vel, 1.0 / (totalsteps * dt * sds->scale));
// mul_v3_fl(vel, 1.0 / dt);
// DG TODO: cap velocity to maxVelMag (or maxvel)
// oldpos + velocity * dt = newpos
get_cell(sds->p0, sds->res, sds->dx*sds->scale, cOldpos /* use current position here instead of "pos" */, cell, 0);
// check if cell is valid (in the domain boundary)
for(j = 0; j < 3; j++)
if((cell[j] > sds->res[j] - 1) || (cell[j] < 0))
{
badcell = 1;
break;
}
if(badcell)
continue;
// 2. set cell values (heat, density and velocity)
index = smoke_get_index(cell[0], sds->res[0], cell[1], sds->res[1], cell[2]);
// Don't overwrite existing obstacles
if(obstacles[index])
continue;
// printf("cell[0]: %d, cell[1]: %d, cell[2]: %d\n", cell[0], cell[1], cell[2]);
// printf("res[0]: %d, res[1]: %d, res[2]: %d, index: %d\n\n", sds->res[0], sds->res[1], sds->res[2], index);
obstacles[index] = 1 | 8 /* ANIMATED */;
if(len_v3(vel) > FLT_EPSILON)
{
// Collision object is moving
velx[index] = vel[0]; // use "+="?
vely[index] = vel[1];
velz[index] = vel[2];
}
}
obstacles_from_derivedmesh(collob, sds, scs, obstacles, velx, vely, velz, dt);
}
}
if(collobjs)
MEM_freeN(collobjs);
/* obstacle cells should not contain any velocity from the smoke simulation */
for(z = 0; z < sds->res[0] * sds->res[1] * sds->res[2]; z++)
{
if(obstacles[z])
{
velxOrig[z] = 0;
velyOrig[z] = 0;
velzOrig[z] = 0;
density[z] = 0;
}
}
}
static void update_flowsfluids(Scene *scene, Object *ob, SmokeDomainSettings *sds, float time)
@@ -1656,88 +1269,22 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
}
else if(smd->type & MOD_SMOKE_TYPE_COLL)
{
/* Check if domain resolution changed */
/* DG TODO: can this be solved more elegant using dependancy graph? */
{
SmokeCollSettings *scs = smd->coll;
Base *base = scene->base.first;
int changed = 0;
float dx = FLT_MAX;
float scale = 1.0f;
int haveDomain = 0;
for ( ; base; base = base->next)
{
SmokeModifierData *smd2 = (SmokeModifierData *)modifiers_findByType(base->object, eModifierType_Smoke);
if (smd2 && (smd2->type & MOD_SMOKE_TYPE_DOMAIN) && smd2->domain)
{
SmokeDomainSettings *sds = smd2->domain;
if(sds->dx * sds->scale < dx)
{
dx = sds->dx;
scale = sds->scale;
changed = 1;
}
haveDomain = 1;
}
}
if(!haveDomain)
return;
if(changed)
{
if(dx*scale != scs->dx)
{
scs->dx = dx*scale;
smokeModifier_reset(smd);
}
}
}
if(scene->r.cfra >= smd->time)
smokeModifier_init(smd, ob, scene, dm);
if(smd->coll)
{
if (smd->coll->dm)
smd->coll->dm->release(smd->coll->dm);
smd->coll->dm = CDDM_copy(dm);
DM_ensure_tessface(smd->coll->dm);
}
if(scene->r.cfra > smd->time)
{
unsigned int i;
SmokeCollSettings *scs = smd->coll;
float *points_old = scs->points_old;
float *points = scs->points;
unsigned int numpoints = scs->numpoints;
// XXX TODO <-- DG: what is TODO here?
smd->time = scene->r.cfra;
// rigid movement support
copy_m4_m4(scs->mat_old, scs->mat);
copy_m4_m4(scs->mat, ob->obmat);
if(scs->type != SM_COLL_ANIMATED) // if(not_animated)
{
// nothing to do, "mat" is already up to date
}
else
{
// XXX TODO: need to update positions + divs
if(scs->numverts != dm->getNumVerts(dm))
{
// DG TODO: reset modifier?
return;
}
for(i = 0; i < numpoints * 3; i++)
{
points_old[i] = points[i];
}
DM_ensure_tessface(dm);
fill_scs_points_anim(ob, dm, scs);
}
}
else if(scene->r.cfra < smd->time)
{
@@ -1803,7 +1350,7 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
if (framenr != scene->r.cfra)
return;
tstart();
// tstart();
smoke_calc_domain(scene, ob, smd);
@@ -1855,7 +1402,7 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
if(framenr != startframe)
BKE_ptcache_write(&pid, framenr);
tend();
//tend();
// printf ( "Frame: %d, Time: %f\n\n", (int)smd->time, (float) tval() );
}
}

View File

@@ -4402,8 +4402,9 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
smd->coll = newdataadr(fd, smd->coll);
smd->coll->smd = smd;
if (smd->coll) {
smd->coll->points = NULL;
smd->coll->numpoints = 0;
smd->coll->verts_old = NULL;
smd->coll->numverts = 0;
smd->coll->dm = NULL;
}
else
smd->type = 0;

View File

@@ -6996,6 +6996,8 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
smd->domain->res, smd->domain->dx,
smd->domain->tex_shadow);
GPU_free_smoke(smd);
// draw_smoke_heat(smd->domain);
// draw_smoke_velocity(smd->domain);
// #endif
#if 0
int x, y, z;

View File

@@ -36,6 +36,7 @@
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_smoke_types.h"
#include "DNA_view3d_types.h"
#include "BLI_utildefines.h"
@@ -454,3 +455,83 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float min[3], float max[3], int r
glDepthMask(GL_TRUE);
}
}
void draw_smoke_velocity(SmokeDomainSettings *domain)
{
float x,y,z;
int *res = domain->res;
float *vel_x = smoke_get_velocity_x(domain->fluid);
float *vel_y = smoke_get_velocity_y(domain->fluid);
float *vel_z = smoke_get_velocity_z(domain->fluid);
float *density = smoke_get_density(domain->fluid);
float *min = domain->p0;
float cell_size = domain->dx * domain->scale;
float step_size = ((float)MAX3(res[0], res[1], res[2]))/16.f;
float vf = domain->scale / 16.f * 2.f;
glColor3f(1.0f, 0.5f, 0.0f);
glLineWidth(1.0f);
for (x=0; x<res[0]; x+=step_size)
for (y=0; y<res[1]; y+=step_size)
for (z=0; z<res[2]; z+=step_size) {
int index = floor(x) + floor(y)*res[0] + floor(z)*res[0]*res[1];
float pos[3] = {min[0]+((float)x + 0.5f)*cell_size, min[1]+((float)y + 0.5f)*cell_size, min[2]+((float)z + 0.5f)*cell_size};
float vel = sqrtf(vel_x[index]*vel_x[index] + vel_y[index]*vel_y[index] + vel_z[index]*vel_z[index]);
if (vel > 0.01f) {
float col_g = 1.0f - vel;
CLAMP(col_g, 0.0f, 1.0f);
glColor3f(1.0f, col_g, 0.0f);
glPointSize(10.0f * vel);
glBegin(GL_LINES);
glVertex3f(pos[0], pos[1], pos[2]);
glVertex3f(pos[0]+vel_x[index]*vf, pos[1]+vel_y[index]*vf, pos[2]+vel_z[index]*vf);
glEnd();
glBegin(GL_POINTS);
glVertex3f(pos[0]+vel_x[index]*vf, pos[1]+vel_y[index]*vf, pos[2]+vel_z[index]*vf);
glEnd();
}
}
}
void draw_smoke_heat(SmokeDomainSettings *domain)
{
float x,y,z;
int *res = domain->res;
// float *heat = smoke_get_heat(domain->fluid);
unsigned char *heat = smoke_get_obstacle(domain->fluid);
float *min = domain->p0;
float cell_size = domain->dx * domain->scale;
//float step_size = ((float)MAX3(res[0], res[1], res[2]))/16.f;
float step_size = 1.0f;
for (x=0; x<res[0]; x+=step_size)
for (y=0; y<res[1]; y+=step_size)
for (z=0; z<res[2]; z+=step_size) {
int index = floor(x) + floor(y)*res[0] + floor(z)*res[0]*res[1];
float pos[3] = {min[0]+((float)x + 0.5f)*cell_size, min[1]+((float)y + 0.5f)*cell_size, min[2]+((float)z + 0.5f)*cell_size};
if (heat[index] > 0) {
GLUquadricObj *qobj = gluNewQuadric();
gluQuadricDrawStyle(qobj, GLU_FILL);
glColor3f(0, 0, 1.0f);
glPushMatrix();
glTranslatef(pos[0], pos[1], pos[2]);
glScalef(domain->dx * domain->scale * 0.1, domain->dx * domain->scale * 0.1, domain->dx * domain->scale * 0.1);
gluSphere(qobj, 1.0, 8, 5);
glPopMatrix();
gluDeleteQuadric(qobj);
}
}
}

View File

@@ -213,6 +213,8 @@ extern const char *view3d_context_dir[]; /* doc access */
/* draw_volume.c */
void draw_volume(struct ARegion *ar, struct GPUTexture *tex, float min[3], float max[3], int res[3], float dx, struct GPUTexture *tex_shadow);
void draw_smoke_velocity(struct SmokeDomainSettings *domain);
void draw_smoke_heat(struct SmokeDomainSettings *domain);
/* workaround for trivial but noticeable camera bug caused by imprecision
* between view border calculation in 2D/3D space, workaround for bug [#28037].

View File

@@ -131,28 +131,14 @@ typedef struct SmokeFlowSettings {
int flags; /* absolute emission etc*/
} SmokeFlowSettings;
// struct BVHTreeFromMesh *bvh;
// float mat[4][4];
// float mat_old[4][4];
/* collision objects (filled with smoke) */
typedef struct SmokeCollSettings {
struct SmokeModifierData *smd; /* for fast RNA access */
struct BVHTree *bvhtree; /* bounding volume hierarchy for this cloth object */
float *points;
float *points_old;
float *vel; // UNUSED
int *tridivs;
float mat[4][4];
float mat_old[4][4];
int numpoints;
int numverts; // check if mesh changed
int numtris;
float dx; /* global domain cell length taken from (scale / resolution) */
struct DerivedMesh *dm;
float *verts_old;
int numverts;
short type; // static = 0, rigid = 1, dynamic = 2
short pad;
int pad2;
} SmokeCollSettings;
#endif

View File

@@ -113,7 +113,7 @@ static char *rna_SmokeCollSettings_path(PointerRNA *ptr)
return BLI_sprintfN("modifiers[\"%s\"].coll_settings", md->name);
}
static int rna_SmokeModifier_density_get_length(PointerRNA *ptr, int length[RNA_MAX_ARRAY_DIMENSION])
int rna_SmokeModifier_density_get_length(PointerRNA *ptr, int length[3])
{
SmokeDomainSettings *settings = (SmokeDomainSettings *)ptr->data;
@@ -133,7 +133,7 @@ static int rna_SmokeModifier_density_get_length(PointerRNA *ptr, int length[RNA_
return length[0];
}
static void rna_SmokeModifier_density_get(PointerRNA *ptr, float *values)
void rna_SmokeModifier_density_get(PointerRNA *ptr, float *values)
{
SmokeDomainSettings *settings = (SmokeDomainSettings *)ptr->data;
float *density = smoke_get_density(settings->fluid);